* Moves multi-collection files into their own directory, and splits them into seperate files
* Changes exports so that each collection has its own module
* Adds underscores to public modules and filenames to match standard naming conventions
(that is, treemap::{TreeMap, TreeSet} => tree_map::TreeMap, tree_set::TreeSet)
* Renames PriorityQueue to BinaryHeap
* Renames SmallIntMap to VecMap
* Miscellanious fallout fixes
[breaking-change]
```
use std::iter::range_step;
use std::option::{Some, None};
-use std::collections::hashmap::{mod, HashMap};
+use std::collections::hash_map::{mod, HashMap};
-# fn foo<T>(_: T){}
-# fn bar(map: HashMap<String, uint>, set: hashmap::HashSet<String>){}
+fn foo<T>(_: T){}
+fn bar(map1: HashMap<String, uint>, map2: hash_map::HashMap<String, uint>){}
fn main() {
// Equivalent to 'std::iter::range_step(0u, 10u, 2u);'
// std::option::None]);'
foo(vec![Some(1.0f64), None]);
- // Both `hash` and `HashMap` are in scope.
- let map = HashMap::new();
- let set = hashmap::HashSet::new();
- bar(map, set);
+ // Both `hash_map` and `HashMap` are in scope.
+ let map1 = HashMap::new();
+ let map2 = hash_map::HashMap::new();
+ bar(map1, map2);
}
```
* running
* blocked
-* panicked
+* panicked
* dead
A task begins its lifecycle — once it has been spawned — in the
--- /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.
+
+//! A priority queue implemented with a binary heap.
+//!
+//! Insertions have `O(log n)` time complexity and checking or popping the largest element is
+//! `O(1)`. Converting a vector to a priority queue can be done in-place, and has `O(n)`
+//! complexity. A priority queue can also be converted to a sorted vector in-place, allowing it to
+//! be used for an `O(n log n)` in-place heapsort.
+//!
+//! # Example
+//!
+//! This is a larger example which implements [Dijkstra's algorithm][dijkstra]
+//! to solve the [shortest path problem][sssp] on a [directed graph][dir_graph].
+//! It showcases how to use the `BinaryHeap` with custom types.
+//!
+//! [dijkstra]: http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
+//! [sssp]: http://en.wikipedia.org/wiki/Shortest_path_problem
+//! [dir_graph]: http://en.wikipedia.org/wiki/Directed_graph
+//!
+//! ```
+//! use std::collections::BinaryHeap;
+//! use std::uint;
+//!
+//! #[deriving(Eq, PartialEq)]
+//! struct State {
+//! cost: uint,
+//! position: uint
+//! }
+//!
+//! // The priority queue depends on `Ord`.
+//! // Explicitly implement the trait so the queue becomes a min-heap
+//! // instead of a max-heap.
+//! impl Ord for State {
+//! fn cmp(&self, other: &State) -> Ordering {
+//! // Notice that the we flip the ordering here
+//! other.cost.cmp(&self.cost)
+//! }
+//! }
+//!
+//! // `PartialOrd` needs to be implemented as well.
+//! impl PartialOrd for State {
+//! fn partial_cmp(&self, other: &State) -> Option<Ordering> {
+//! Some(self.cmp(other))
+//! }
+//! }
+//!
+//! // Each node is represented as an `uint`, for a shorter implementation.
+//! struct Edge {
+//! node: uint,
+//! cost: uint
+//! }
+//!
+//! // Dijkstra's shortest path algorithm.
+//!
+//! // Start at `start` and use `dist` to track the current shortest distance
+//! // to each node. This implementation isn't memory efficient as it may leave duplicate
+//! // nodes in the queue. It also uses `uint::MAX` as a sentinel value,
+//! // for a simpler implementation.
+//! fn shortest_path(adj_list: &Vec<Vec<Edge>>, start: uint, goal: uint) -> uint {
+//! // dist[node] = current shortest distance from `start` to `node`
+//! let mut dist = Vec::from_elem(adj_list.len(), uint::MAX);
+//!
+//! let mut pq = BinaryHeap::new();
+//!
+//! // We're at `start`, with a zero cost
+//! dist[start] = 0u;
+//! pq.push(State { cost: 0u, position: start });
+//!
+//! // Examine the frontier with lower cost nodes first (min-heap)
+//! loop {
+//! let State { cost, position } = match pq.pop() {
+//! None => break, // empty
+//! Some(s) => s
+//! };
+//!
+//! // Alternatively we could have continued to find all shortest paths
+//! if position == goal { return cost }
+//!
+//! // Important as we may have already found a better way
+//! if cost > dist[position] { continue }
+//!
+//! // For each node we can reach, see if we can find a way with
+//! // a lower cost going through this node
+//! for edge in adj_list[position].iter() {
+//! let next = State { cost: cost + edge.cost, position: edge.node };
+//!
+//! // If so, add it to the frontier and continue
+//! if next.cost < dist[next.position] {
+//! pq.push(next);
+//! // Relaxation, we have now found a better way
+//! dist[next.position] = next.cost;
+//! }
+//! }
+//! }
+//!
+//! // Goal not reachable
+//! uint::MAX
+//! }
+//!
+//! fn main() {
+//! // This is the directed graph we're going to use.
+//! // The node numbers correspond to the different states,
+//! // and the edge weights symbolises the cost of moving
+//! // from one node to another.
+//! // Note that the edges are one-way.
+//! //
+//! // 7
+//! // +-----------------+
+//! // | |
+//! // v 1 2 |
+//! // 0 -----> 1 -----> 3 ---> 4
+//! // | ^ ^ ^
+//! // | | 1 | |
+//! // | | | 3 | 1
+//! // +------> 2 -------+ |
+//! // 10 | |
+//! // +---------------+
+//! //
+//! // The graph is represented as an adjacency list where each index,
+//! // corresponding to a node value, has a list of outgoing edges.
+//! // Chosen for it's efficiency.
+//! let graph = vec![
+//! // Node 0
+//! vec![Edge { node: 2, cost: 10 },
+//! Edge { node: 1, cost: 1 }],
+//! // Node 1
+//! vec![Edge { node: 3, cost: 2 }],
+//! // Node 2
+//! vec![Edge { node: 1, cost: 1 },
+//! Edge { node: 3, cost: 3 },
+//! Edge { node: 4, cost: 1 }],
+//! // Node 3
+//! vec![Edge { node: 0, cost: 7 },
+//! Edge { node: 4, cost: 2 }],
+//! // Node 4
+//! vec![]];
+//!
+//! assert_eq!(shortest_path(&graph, 0, 1), 1);
+//! assert_eq!(shortest_path(&graph, 0, 3), 3);
+//! assert_eq!(shortest_path(&graph, 3, 0), 7);
+//! assert_eq!(shortest_path(&graph, 0, 4), 5);
+//! assert_eq!(shortest_path(&graph, 4, 0), uint::MAX);
+//! }
+//! ```
+
+#![allow(missing_docs)]
+
+use core::prelude::*;
+
+use core::default::Default;
+use core::mem::{zeroed, replace, swap};
+use core::ptr;
+
+use slice;
+use vec::Vec;
+
+/// A priority queue implemented with a binary heap.
+///
+/// This will be a max-heap.
+#[deriving(Clone)]
+pub struct BinaryHeap<T> {
+ data: Vec<T>,
+}
+
+impl<T: Ord> Default for BinaryHeap<T> {
+ #[inline]
+ fn default() -> BinaryHeap<T> { BinaryHeap::new() }
+}
+
+impl<T: Ord> BinaryHeap<T> {
+ /// Creates an empty `BinaryHeap` as a max-heap.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BinaryHeap;
+ /// let pq: BinaryHeap<uint> = BinaryHeap::new();
+ /// ```
+ pub fn new() -> BinaryHeap<T> { BinaryHeap{data: vec!(),} }
+
+ /// Creates an empty `BinaryHeap` with a specific capacity.
+ /// This preallocates enough memory for `capacity` elements,
+ /// so that the `BinaryHeap` does not have to be reallocated
+ /// until it contains at least that many values.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BinaryHeap;
+ /// let pq: BinaryHeap<uint> = BinaryHeap::with_capacity(10u);
+ /// ```
+ pub fn with_capacity(capacity: uint) -> BinaryHeap<T> {
+ BinaryHeap { data: Vec::with_capacity(capacity) }
+ }
+
+ /// Creates a `BinaryHeap` from a vector. This is sometimes called
+ /// `heapifying` the vector.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BinaryHeap;
+ /// let pq = BinaryHeap::from_vec(vec![9i, 1, 2, 7, 3, 2]);
+ /// ```
+ pub fn from_vec(xs: Vec<T>) -> BinaryHeap<T> {
+ let mut q = BinaryHeap{data: xs,};
+ let mut n = q.len() / 2;
+ while n > 0 {
+ n -= 1;
+ q.siftdown(n)
+ }
+ q
+ }
+
+ /// An iterator visiting all values in underlying vector, in
+ /// arbitrary order.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BinaryHeap;
+ /// let pq = BinaryHeap::from_vec(vec![1i, 2, 3, 4]);
+ ///
+ /// // Print 1, 2, 3, 4 in arbitrary order
+ /// for x in pq.iter() {
+ /// println!("{}", x);
+ /// }
+ /// ```
+ pub fn iter<'a>(&'a self) -> Items<'a, T> {
+ Items { iter: self.data.iter() }
+ }
+
+ /// Returns the greatest item in a queue, or `None` if it is empty.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BinaryHeap;
+ ///
+ /// let mut pq = BinaryHeap::new();
+ /// assert_eq!(pq.top(), None);
+ ///
+ /// pq.push(1i);
+ /// pq.push(5i);
+ /// pq.push(2i);
+ /// assert_eq!(pq.top(), Some(&5i));
+ ///
+ /// ```
+ pub fn top<'a>(&'a self) -> Option<&'a T> {
+ if self.is_empty() { None } else { Some(&self.data[0]) }
+ }
+
+ /// Returns the number of elements the queue can hold without reallocating.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BinaryHeap;
+ ///
+ /// let pq: BinaryHeap<uint> = BinaryHeap::with_capacity(100u);
+ /// assert!(pq.capacity() >= 100u);
+ /// ```
+ pub fn capacity(&self) -> uint { self.data.capacity() }
+
+ /// Reserves capacity for exactly `n` elements in the `BinaryHeap`.
+ /// Do nothing if the capacity is already sufficient.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BinaryHeap;
+ ///
+ /// let mut pq: BinaryHeap<uint> = BinaryHeap::new();
+ /// pq.reserve_exact(100u);
+ /// assert!(pq.capacity() == 100u);
+ /// ```
+ pub fn reserve_exact(&mut self, n: uint) { self.data.reserve_exact(n) }
+
+ /// Reserves capacity for at least `n` elements in the `BinaryHeap`.
+ /// Do nothing if the capacity is already sufficient.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BinaryHeap;
+ ///
+ /// let mut pq: BinaryHeap<uint> = BinaryHeap::new();
+ /// pq.reserve(100u);
+ /// assert!(pq.capacity() >= 100u);
+ /// ```
+ pub fn reserve(&mut self, n: uint) {
+ self.data.reserve(n)
+ }
+
+ /// Removes the greatest item from a queue and returns it, or `None` if it
+ /// is empty.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BinaryHeap;
+ ///
+ /// let mut pq = BinaryHeap::from_vec(vec![1i, 3]);
+ ///
+ /// assert_eq!(pq.pop(), Some(3i));
+ /// assert_eq!(pq.pop(), Some(1i));
+ /// assert_eq!(pq.pop(), None);
+ /// ```
+ pub fn pop(&mut self) -> Option<T> {
+ match self.data.pop() {
+ None => { None }
+ Some(mut item) => {
+ if !self.is_empty() {
+ swap(&mut item, &mut self.data[0]);
+ self.siftdown(0);
+ }
+ Some(item)
+ }
+ }
+ }
+
+ /// Pushes an item onto the queue.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BinaryHeap;
+ ///
+ /// let mut pq = BinaryHeap::new();
+ /// pq.push(3i);
+ /// pq.push(5i);
+ /// pq.push(1i);
+ ///
+ /// assert_eq!(pq.len(), 3);
+ /// assert_eq!(pq.top(), Some(&5i));
+ /// ```
+ pub fn push(&mut self, item: T) {
+ self.data.push(item);
+ let new_len = self.len() - 1;
+ self.siftup(0, new_len);
+ }
+
+ /// Pushes an item onto a queue then pops the greatest item off the queue in
+ /// an optimized fashion.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BinaryHeap;
+ ///
+ /// let mut pq = BinaryHeap::new();
+ /// pq.push(1i);
+ /// pq.push(5i);
+ ///
+ /// assert_eq!(pq.push_pop(3i), 5);
+ /// assert_eq!(pq.push_pop(9i), 9);
+ /// assert_eq!(pq.len(), 2);
+ /// assert_eq!(pq.top(), Some(&3i));
+ /// ```
+ pub fn push_pop(&mut self, mut item: T) -> T {
+ if !self.is_empty() && *self.top().unwrap() > item {
+ swap(&mut item, &mut self.data[0]);
+ self.siftdown(0);
+ }
+ item
+ }
+
+ /// Pops the greatest item off a queue then pushes an item onto the queue in
+ /// an optimized fashion. The push is done regardless of whether the queue
+ /// was empty.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BinaryHeap;
+ ///
+ /// let mut pq = BinaryHeap::new();
+ ///
+ /// assert_eq!(pq.replace(1i), None);
+ /// assert_eq!(pq.replace(3i), Some(1i));
+ /// assert_eq!(pq.len(), 1);
+ /// assert_eq!(pq.top(), Some(&3i));
+ /// ```
+ pub fn replace(&mut self, mut item: T) -> Option<T> {
+ if !self.is_empty() {
+ swap(&mut item, &mut self.data[0]);
+ self.siftdown(0);
+ Some(item)
+ } else {
+ self.push(item);
+ None
+ }
+ }
+
+ /// Consumes the `BinaryHeap` and returns the underlying vector
+ /// in arbitrary order.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BinaryHeap;
+ ///
+ /// let pq = BinaryHeap::from_vec(vec![1i, 2, 3, 4, 5, 6, 7]);
+ /// let vec = pq.into_vec();
+ ///
+ /// // Will print in some order
+ /// for x in vec.iter() {
+ /// println!("{}", x);
+ /// }
+ /// ```
+ pub fn into_vec(self) -> Vec<T> { let BinaryHeap{data: v} = self; v }
+
+ /// Consumes the `BinaryHeap` and returns a vector in sorted
+ /// (ascending) order.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BinaryHeap;
+ ///
+ /// let mut pq = BinaryHeap::from_vec(vec![1i, 2, 4, 5, 7]);
+ /// pq.push(6);
+ /// pq.push(3);
+ ///
+ /// let vec = pq.into_sorted_vec();
+ /// assert_eq!(vec, vec![1i, 2, 3, 4, 5, 6, 7]);
+ /// ```
+ pub fn into_sorted_vec(self) -> Vec<T> {
+ let mut q = self;
+ let mut end = q.len();
+ while end > 1 {
+ end -= 1;
+ q.data.as_mut_slice().swap(0, end);
+ q.siftdown_range(0, end)
+ }
+ q.into_vec()
+ }
+
+ // The implementations of siftup and siftdown use unsafe blocks in
+ // order to move an element out of the vector (leaving behind a
+ // zeroed element), shift along the others and move it back into the
+ // vector over the junk element. This reduces the constant factor
+ // compared to using swaps, which involves twice as many moves.
+ fn siftup(&mut self, start: uint, mut pos: uint) {
+ unsafe {
+ let new = replace(&mut self.data[pos], zeroed());
+
+ while pos > start {
+ let parent = (pos - 1) >> 1;
+ if new > self.data[parent] {
+ let x = replace(&mut self.data[parent], zeroed());
+ ptr::write(&mut self.data[pos], x);
+ pos = parent;
+ continue
+ }
+ break
+ }
+ ptr::write(&mut self.data[pos], new);
+ }
+ }
+
+ fn siftdown_range(&mut self, mut pos: uint, end: uint) {
+ unsafe {
+ let start = pos;
+ let new = replace(&mut self.data[pos], zeroed());
+
+ let mut child = 2 * pos + 1;
+ while child < end {
+ let right = child + 1;
+ if right < end && !(self.data[child] > self.data[right]) {
+ child = right;
+ }
+ let x = replace(&mut self.data[child], zeroed());
+ ptr::write(&mut self.data[pos], x);
+ pos = child;
+ child = 2 * pos + 1;
+ }
+
+ ptr::write(&mut self.data[pos], new);
+ self.siftup(start, pos);
+ }
+ }
+
+ fn siftdown(&mut self, pos: uint) {
+ let len = self.len();
+ self.siftdown_range(pos, len);
+ }
+
+ /// Returns the length of the queue.
+ pub fn len(&self) -> uint { self.data.len() }
+
+ /// Returns true if the queue contains no elements
+ pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+ /// Drops all items from the queue.
+ pub fn clear(&mut self) { self.data.truncate(0) }
+}
+
+/// `BinaryHeap` iterator.
+pub struct Items <'a, T:'a> {
+ iter: slice::Items<'a, T>,
+}
+
+impl<'a, T> Iterator<&'a T> for Items<'a, T> {
+ #[inline]
+ fn next(&mut self) -> Option<(&'a T)> { self.iter.next() }
+
+ #[inline]
+ fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
+}
+
+impl<T: Ord> FromIterator<T> for BinaryHeap<T> {
+ fn from_iter<Iter: Iterator<T>>(mut iter: Iter) -> BinaryHeap<T> {
+ let vec: Vec<T> = iter.collect();
+ BinaryHeap::from_vec(vec)
+ }
+}
+
+impl<T: Ord> Extendable<T> for BinaryHeap<T> {
+ fn extend<Iter: Iterator<T>>(&mut self, mut iter: Iter) {
+ let (lower, _) = iter.size_hint();
+
+ let len = self.capacity();
+ self.reserve(len + lower);
+
+ for elem in iter {
+ self.push(elem);
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use std::prelude::*;
+
+ use super::BinaryHeap;
+ use vec::Vec;
+
+ #[test]
+ fn test_iterator() {
+ let data = vec!(5i, 9, 3);
+ let iterout = [9i, 5, 3];
+ let pq = BinaryHeap::from_vec(data);
+ let mut i = 0;
+ for el in pq.iter() {
+ assert_eq!(*el, iterout[i]);
+ i += 1;
+ }
+ }
+
+ #[test]
+ fn test_top_and_pop() {
+ let data = vec!(2u, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1);
+ let mut sorted = data.clone();
+ sorted.sort();
+ let mut heap = BinaryHeap::from_vec(data);
+ while !heap.is_empty() {
+ assert_eq!(heap.top().unwrap(), sorted.last().unwrap());
+ assert_eq!(heap.pop().unwrap(), sorted.pop().unwrap());
+ }
+ }
+
+ #[test]
+ fn test_push() {
+ let mut heap = BinaryHeap::from_vec(vec!(2i, 4, 9));
+ assert_eq!(heap.len(), 3);
+ assert!(*heap.top().unwrap() == 9);
+ heap.push(11);
+ assert_eq!(heap.len(), 4);
+ assert!(*heap.top().unwrap() == 11);
+ heap.push(5);
+ assert_eq!(heap.len(), 5);
+ assert!(*heap.top().unwrap() == 11);
+ heap.push(27);
+ assert_eq!(heap.len(), 6);
+ assert!(*heap.top().unwrap() == 27);
+ heap.push(3);
+ assert_eq!(heap.len(), 7);
+ assert!(*heap.top().unwrap() == 27);
+ heap.push(103);
+ assert_eq!(heap.len(), 8);
+ assert!(*heap.top().unwrap() == 103);
+ }
+
+ #[test]
+ fn test_push_unique() {
+ let mut heap = BinaryHeap::from_vec(vec!(box 2i, box 4, box 9));
+ assert_eq!(heap.len(), 3);
+ assert!(*heap.top().unwrap() == box 9);
+ heap.push(box 11);
+ assert_eq!(heap.len(), 4);
+ assert!(*heap.top().unwrap() == box 11);
+ heap.push(box 5);
+ assert_eq!(heap.len(), 5);
+ assert!(*heap.top().unwrap() == box 11);
+ heap.push(box 27);
+ assert_eq!(heap.len(), 6);
+ assert!(*heap.top().unwrap() == box 27);
+ heap.push(box 3);
+ assert_eq!(heap.len(), 7);
+ assert!(*heap.top().unwrap() == box 27);
+ heap.push(box 103);
+ assert_eq!(heap.len(), 8);
+ assert!(*heap.top().unwrap() == box 103);
+ }
+
+ #[test]
+ fn test_push_pop() {
+ let mut heap = BinaryHeap::from_vec(vec!(5i, 5, 2, 1, 3));
+ assert_eq!(heap.len(), 5);
+ assert_eq!(heap.push_pop(6), 6);
+ assert_eq!(heap.len(), 5);
+ assert_eq!(heap.push_pop(0), 5);
+ assert_eq!(heap.len(), 5);
+ assert_eq!(heap.push_pop(4), 5);
+ assert_eq!(heap.len(), 5);
+ assert_eq!(heap.push_pop(1), 4);
+ assert_eq!(heap.len(), 5);
+ }
+
+ #[test]
+ fn test_replace() {
+ let mut heap = BinaryHeap::from_vec(vec!(5i, 5, 2, 1, 3));
+ assert_eq!(heap.len(), 5);
+ assert_eq!(heap.replace(6).unwrap(), 5);
+ assert_eq!(heap.len(), 5);
+ assert_eq!(heap.replace(0).unwrap(), 6);
+ assert_eq!(heap.len(), 5);
+ assert_eq!(heap.replace(4).unwrap(), 5);
+ assert_eq!(heap.len(), 5);
+ assert_eq!(heap.replace(1).unwrap(), 4);
+ assert_eq!(heap.len(), 5);
+ }
+
+ fn check_to_vec(mut data: Vec<int>) {
+ let heap = BinaryHeap::from_vec(data.clone());
+ let mut v = heap.clone().into_vec();
+ v.sort();
+ data.sort();
+
+ assert_eq!(v.as_slice(), data.as_slice());
+ assert_eq!(heap.into_sorted_vec().as_slice(), data.as_slice());
+ }
+
+ #[test]
+ fn test_to_vec() {
+ check_to_vec(vec!());
+ check_to_vec(vec!(5i));
+ check_to_vec(vec!(3i, 2));
+ check_to_vec(vec!(2i, 3));
+ check_to_vec(vec!(5i, 1, 2));
+ check_to_vec(vec!(1i, 100, 2, 3));
+ check_to_vec(vec!(1i, 3, 5, 7, 9, 2, 4, 6, 8, 0));
+ check_to_vec(vec!(2i, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1));
+ check_to_vec(vec!(9i, 11, 9, 9, 9, 9, 11, 2, 3, 4, 11, 9, 0, 0, 0, 0));
+ check_to_vec(vec!(0i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
+ check_to_vec(vec!(10i, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0));
+ check_to_vec(vec!(0i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 1, 2));
+ check_to_vec(vec!(5i, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1));
+ }
+
+ #[test]
+ fn test_empty_pop() {
+ let mut heap: BinaryHeap<int> = BinaryHeap::new();
+ assert!(heap.pop().is_none());
+ }
+
+ #[test]
+ fn test_empty_top() {
+ let empty: BinaryHeap<int> = BinaryHeap::new();
+ assert!(empty.top().is_none());
+ }
+
+ #[test]
+ fn test_empty_replace() {
+ let mut heap: BinaryHeap<int> = BinaryHeap::new();
+ heap.replace(5).is_none();
+ }
+
+ #[test]
+ fn test_from_iter() {
+ let xs = vec!(9u, 8, 7, 6, 5, 4, 3, 2, 1);
+
+ let mut q: BinaryHeap<uint> = xs.as_slice().iter().rev().map(|&x| x).collect();
+
+ for &x in xs.iter() {
+ assert_eq!(q.pop().unwrap(), x);
+ }
+ }
+}
--- /dev/null
+// Copyright 2012-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.
+
+// FIXME(Gankro): Bitv and BitvSet are very tightly coupled. Ideally (for maintenance),
+// they should be in separate files/modules, with BitvSet only using Bitv's public API.
+
+//! Collections implemented with bit vectors.
+//!
+//! # Example
+//!
+//! This is a simple example of the [Sieve of Eratosthenes][sieve]
+//! which calculates prime numbers up to a given limit.
+//!
+//! [sieve]: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
+//!
+//! ```
+//! use std::collections::{BitvSet, Bitv};
+//! use std::iter;
+//!
+//! let max_prime = 10000;
+//!
+//! // Store the primes as a BitvSet
+//! let primes = {
+//! // Assume all numbers are prime to begin, and then we
+//! // cross off non-primes progressively
+//! let mut bv = Bitv::with_capacity(max_prime, true);
+//!
+//! // Neither 0 nor 1 are prime
+//! bv.set(0, false);
+//! bv.set(1, false);
+//!
+//! for i in iter::range_inclusive(2, (max_prime as f64).sqrt() as uint) {
+//! // if i is a prime
+//! if bv[i] {
+//! // Mark all multiples of i as non-prime (any multiples below i * i
+//! // will have been marked as non-prime previously)
+//! for j in iter::range_step(i * i, max_prime, i) { bv.set(j, false) }
+//! }
+//! }
+//! BitvSet::from_bitv(bv)
+//! };
+//!
+//! // Simple primality tests below our max bound
+//! let print_primes = 20;
+//! print!("The primes below {} are: ", print_primes);
+//! for x in range(0, print_primes) {
+//! if primes.contains(&x) {
+//! print!("{} ", x);
+//! }
+//! }
+//! println!("");
+//!
+//! // We can manipulate the internal Bitv
+//! let num_primes = primes.get_ref().iter().filter(|x| *x).count();
+//! println!("There are {} primes below {}", num_primes, max_prime);
+//! ```
+
+use core::prelude::*;
+
+use core::cmp;
+use core::default::Default;
+use core::fmt;
+use core::iter::{Chain, Enumerate, Repeat, Skip, Take};
+use core::iter;
+use core::slice;
+use core::u32;
+use std::hash;
+
+use vec::Vec;
+
+type MatchWords<'a> = Chain<MaskWords<'a>, Skip<Take<Enumerate<Repeat<u32>>>>>;
+// Take two BitV's, and return iterators of their words, where the shorter one
+// has been padded with 0's
+fn match_words <'a,'b>(a: &'a Bitv, b: &'b Bitv) -> (MatchWords<'a>, MatchWords<'b>) {
+ let a_len = a.storage.len();
+ let b_len = b.storage.len();
+
+ // have to uselessly pretend to pad the longer one for type matching
+ if a_len < b_len {
+ (a.mask_words(0).chain(Repeat::new(0u32).enumerate().take(b_len).skip(a_len)),
+ b.mask_words(0).chain(Repeat::new(0u32).enumerate().take(0).skip(0)))
+ } else {
+ (a.mask_words(0).chain(Repeat::new(0u32).enumerate().take(0).skip(0)),
+ b.mask_words(0).chain(Repeat::new(0u32).enumerate().take(a_len).skip(b_len)))
+ }
+}
+
+static TRUE: bool = true;
+static FALSE: bool = false;
+
+/// The bitvector type.
+///
+/// # Example
+///
+/// ```rust
+/// use collections::Bitv;
+///
+/// let mut bv = Bitv::with_capacity(10, false);
+///
+/// // insert all primes less than 10
+/// bv.set(2, true);
+/// bv.set(3, true);
+/// bv.set(5, true);
+/// bv.set(7, true);
+/// println!("{}", bv.to_string());
+/// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
+///
+/// // flip all values in bitvector, producing non-primes less than 10
+/// bv.negate();
+/// println!("{}", bv.to_string());
+/// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
+///
+/// // reset bitvector to empty
+/// bv.clear();
+/// println!("{}", bv.to_string());
+/// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
+/// ```
+pub struct Bitv {
+ /// Internal representation of the bit vector
+ storage: Vec<u32>,
+ /// The number of valid bits in the internal representation
+ nbits: uint
+}
+
+impl Index<uint,bool> for Bitv {
+ #[inline]
+ fn index<'a>(&'a self, i: &uint) -> &'a bool {
+ if self.get(*i) {
+ &TRUE
+ } else {
+ &FALSE
+ }
+ }
+}
+
+struct MaskWords<'a> {
+ iter: slice::Items<'a, u32>,
+ next_word: Option<&'a u32>,
+ last_word_mask: u32,
+ offset: uint
+}
+
+impl<'a> Iterator<(uint, u32)> for MaskWords<'a> {
+ /// Returns (offset, word)
+ #[inline]
+ fn next<'a>(&'a mut self) -> Option<(uint, u32)> {
+ let ret = self.next_word;
+ match ret {
+ Some(&w) => {
+ self.next_word = self.iter.next();
+ self.offset += 1;
+ // The last word may need to be masked
+ if self.next_word.is_none() {
+ Some((self.offset - 1, w & self.last_word_mask))
+ } else {
+ Some((self.offset - 1, w))
+ }
+ },
+ None => None
+ }
+ }
+}
+
+impl Bitv {
+ #[inline]
+ fn process(&mut self, other: &Bitv, op: |u32, u32| -> u32) -> bool {
+ let len = other.storage.len();
+ assert_eq!(self.storage.len(), len);
+ let mut changed = false;
+ // Notice: `a` is *not* masked here, which is fine as long as
+ // `op` is a bitwise operation, since any bits that should've
+ // been masked were fine to change anyway. `b` is masked to
+ // make sure its unmasked bits do not cause damage.
+ for (a, (_, b)) in self.storage.iter_mut()
+ .zip(other.mask_words(0)) {
+ let w = op(*a, b);
+ if *a != w {
+ changed = true;
+ *a = w;
+ }
+ }
+ changed
+ }
+
+ #[inline]
+ fn mask_words<'a>(&'a self, mut start: uint) -> MaskWords<'a> {
+ if start > self.storage.len() {
+ start = self.storage.len();
+ }
+ let mut iter = self.storage[start..].iter();
+ MaskWords {
+ next_word: iter.next(),
+ iter: iter,
+ last_word_mask: {
+ let rem = self.nbits % u32::BITS;
+ if rem > 0 {
+ (1 << rem) - 1
+ } else { !0 }
+ },
+ offset: start
+ }
+ }
+
+ /// Creates an empty `Bitv`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::Bitv;
+ /// let mut bv = Bitv::new();
+ /// ```
+ pub fn new() -> Bitv {
+ Bitv { storage: Vec::new(), nbits: 0 }
+ }
+
+ /// Creates a `Bitv` that holds `nbits` elements, setting each element
+ /// to `init`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::Bitv;
+ ///
+ /// let mut bv = Bitv::with_capacity(10u, false);
+ /// assert_eq!(bv.len(), 10u);
+ /// for x in bv.iter() {
+ /// assert_eq!(x, false);
+ /// }
+ /// ```
+ pub fn with_capacity(nbits: uint, init: bool) -> Bitv {
+ let mut bitv = Bitv {
+ storage: Vec::from_elem((nbits + u32::BITS - 1) / u32::BITS,
+ if init { !0u32 } else { 0u32 }),
+ nbits: nbits
+ };
+
+ // Zero out any unused bits in the highest word if necessary
+ let used_bits = bitv.nbits % u32::BITS;
+ if init && used_bits != 0 {
+ let largest_used_word = (bitv.nbits + u32::BITS - 1) / u32::BITS - 1;
+ bitv.storage[largest_used_word] &= (1 << used_bits) - 1;
+ }
+
+ bitv
+ }
+
+ /// Retrieves the value at index `i`.
+ ///
+ /// # Failure
+ ///
+ /// Fails if `i` is out of bounds.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::bitv;
+ ///
+ /// let bv = bitv::from_bytes([0b01100000]);
+ /// assert_eq!(bv.get(0), false);
+ /// assert_eq!(bv.get(1), true);
+ ///
+ /// // Can also use array indexing
+ /// assert_eq!(bv[1], true);
+ /// ```
+ #[inline]
+ pub fn get(&self, i: uint) -> bool {
+ assert!(i < self.nbits);
+ let w = i / u32::BITS;
+ let b = i % u32::BITS;
+ let x = self.storage[w] & (1 << b);
+ x != 0
+ }
+
+ /// Sets the value of a bit at a index `i`.
+ ///
+ /// # Failure
+ ///
+ /// Fails if `i` is out of bounds.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::Bitv;
+ ///
+ /// let mut bv = Bitv::with_capacity(5, false);
+ /// bv.set(3, true);
+ /// assert_eq!(bv[3], true);
+ /// ```
+ #[inline]
+ pub fn set(&mut self, i: uint, x: bool) {
+ assert!(i < self.nbits);
+ let w = i / u32::BITS;
+ let b = i % u32::BITS;
+ let flag = 1 << b;
+ let val = if x { self.storage[w] | flag }
+ else { self.storage[w] & !flag };
+ self.storage[w] = val;
+ }
+
+ /// Sets all bits to 1.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::bitv;
+ ///
+ /// let before = 0b01100000;
+ /// let after = 0b11111111;
+ ///
+ /// let mut bv = bitv::from_bytes([before]);
+ /// bv.set_all();
+ /// assert_eq!(bv, bitv::from_bytes([after]));
+ /// ```
+ #[inline]
+ pub fn set_all(&mut self) {
+ for w in self.storage.iter_mut() { *w = !0u32; }
+ }
+
+ /// Flips all bits.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::bitv;
+ ///
+ /// let before = 0b01100000;
+ /// let after = 0b10011111;
+ ///
+ /// let mut bv = bitv::from_bytes([before]);
+ /// bv.negate();
+ /// assert_eq!(bv, bitv::from_bytes([after]));
+ /// ```
+ #[inline]
+ pub fn negate(&mut self) {
+ for w in self.storage.iter_mut() { *w = !*w; }
+ }
+
+ /// Calculates the union of two bitvectors. This acts like the bitwise `or`
+ /// function.
+ ///
+ /// Sets `self` to the union of `self` and `other`. Both bitvectors must be
+ /// the same length. Returns `true` if `self` changed.
+ ///
+ /// # Failure
+ ///
+ /// Fails if the bitvectors are of different lengths.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::bitv;
+ ///
+ /// let a = 0b01100100;
+ /// let b = 0b01011010;
+ /// let res = 0b01111110;
+ ///
+ /// let mut a = bitv::from_bytes([a]);
+ /// let b = bitv::from_bytes([b]);
+ ///
+ /// assert!(a.union(&b));
+ /// assert_eq!(a, bitv::from_bytes([res]));
+ /// ```
+ #[inline]
+ pub fn union(&mut self, other: &Bitv) -> bool {
+ self.process(other, |w1, w2| w1 | w2)
+ }
+
+ /// Calculates the intersection of two bitvectors. This acts like the
+ /// bitwise `and` function.
+ ///
+ /// Sets `self` to the intersection of `self` and `other`. Both bitvectors
+ /// must be the same length. Returns `true` if `self` changed.
+ ///
+ /// # Failure
+ ///
+ /// Fails if the bitvectors are of different lengths.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::bitv;
+ ///
+ /// let a = 0b01100100;
+ /// let b = 0b01011010;
+ /// let res = 0b01000000;
+ ///
+ /// let mut a = bitv::from_bytes([a]);
+ /// let b = bitv::from_bytes([b]);
+ ///
+ /// assert!(a.intersect(&b));
+ /// assert_eq!(a, bitv::from_bytes([res]));
+ /// ```
+ #[inline]
+ pub fn intersect(&mut self, other: &Bitv) -> bool {
+ self.process(other, |w1, w2| w1 & w2)
+ }
+
+ /// Calculates the difference between two bitvectors.
+ ///
+ /// Sets each element of `self` to the value of that element minus the
+ /// element of `other` at the same index. Both bitvectors must be the same
+ /// length. Returns `true` if `self` changed.
+ ///
+ /// # Failure
+ ///
+ /// Fails if the bitvectors are of different length.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::bitv;
+ ///
+ /// let a = 0b01100100;
+ /// let b = 0b01011010;
+ /// let a_b = 0b00100100; // a - b
+ /// let b_a = 0b00011010; // b - a
+ ///
+ /// let mut bva = bitv::from_bytes([a]);
+ /// let bvb = bitv::from_bytes([b]);
+ ///
+ /// assert!(bva.difference(&bvb));
+ /// assert_eq!(bva, bitv::from_bytes([a_b]));
+ ///
+ /// let bva = bitv::from_bytes([a]);
+ /// let mut bvb = bitv::from_bytes([b]);
+ ///
+ /// assert!(bvb.difference(&bva));
+ /// assert_eq!(bvb, bitv::from_bytes([b_a]));
+ /// ```
+ #[inline]
+ pub fn difference(&mut self, other: &Bitv) -> bool {
+ self.process(other, |w1, w2| w1 & !w2)
+ }
+
+ /// Returns `true` if all bits are 1.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::Bitv;
+ ///
+ /// let mut bv = Bitv::with_capacity(5, true);
+ /// assert_eq!(bv.all(), true);
+ ///
+ /// bv.set(1, false);
+ /// assert_eq!(bv.all(), false);
+ /// ```
+ #[inline]
+ pub fn all(&self) -> bool {
+ let mut last_word = !0u32;
+ // Check that every word but the last is all-ones...
+ self.mask_words(0).all(|(_, elem)|
+ { let tmp = last_word; last_word = elem; tmp == !0u32 }) &&
+ // ...and that the last word is ones as far as it needs to be
+ (last_word == ((1 << self.nbits % u32::BITS) - 1) || last_word == !0u32)
+ }
+
+ /// Returns an iterator over the elements of the vector in order.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::bitv;
+ ///
+ /// let bv = bitv::from_bytes([0b01110100, 0b10010010]);
+ /// assert_eq!(bv.iter().filter(|x| *x).count(), 7);
+ /// ```
+ #[inline]
+ pub fn iter<'a>(&'a self) -> Bits<'a> {
+ Bits {bitv: self, next_idx: 0, end_idx: self.nbits}
+ }
+
+ /// Returns `true` if all bits are 0.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::Bitv;
+ ///
+ /// let mut bv = Bitv::with_capacity(10, false);
+ /// assert_eq!(bv.none(), true);
+ ///
+ /// bv.set(3, true);
+ /// assert_eq!(bv.none(), false);
+ /// ```
+ pub fn none(&self) -> bool {
+ self.mask_words(0).all(|(_, w)| w == 0)
+ }
+
+ /// Returns `true` if any bit is 1.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::Bitv;
+ ///
+ /// let mut bv = Bitv::with_capacity(10, false);
+ /// assert_eq!(bv.any(), false);
+ ///
+ /// bv.set(3, true);
+ /// assert_eq!(bv.any(), true);
+ /// ```
+ #[inline]
+ pub fn any(&self) -> bool {
+ !self.none()
+ }
+
+ /// Organises the bits into bytes, such that the first bit in the
+ /// `Bitv` becomes the high-order bit of the first byte. If the
+ /// size of the `Bitv` is not a multiple of eight then trailing bits
+ /// will be filled-in with `false`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::Bitv;
+ ///
+ /// let mut bv = Bitv::with_capacity(3, true);
+ /// bv.set(1, false);
+ ///
+ /// assert_eq!(bv.to_bytes(), vec!(0b10100000));
+ ///
+ /// let mut bv = Bitv::with_capacity(9, false);
+ /// bv.set(2, true);
+ /// bv.set(8, true);
+ ///
+ /// assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000));
+ /// ```
+ pub fn to_bytes(&self) -> Vec<u8> {
+ fn bit (bitv: &Bitv, byte: uint, bit: uint) -> u8 {
+ let offset = byte * 8 + bit;
+ if offset >= bitv.nbits {
+ 0
+ } else {
+ bitv.get(offset) as u8 << (7 - bit)
+ }
+ }
+
+ let len = self.nbits/8 +
+ if self.nbits % 8 == 0 { 0 } else { 1 };
+ Vec::from_fn(len, |i|
+ bit(self, i, 0) |
+ bit(self, i, 1) |
+ bit(self, i, 2) |
+ bit(self, i, 3) |
+ bit(self, i, 4) |
+ bit(self, i, 5) |
+ bit(self, i, 6) |
+ bit(self, i, 7)
+ )
+ }
+
+ /// Transforms `self` into a `Vec<bool>` by turning each bit into a `bool`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::bitv;
+ ///
+ /// let bv = bitv::from_bytes([0b10100000]);
+ /// assert_eq!(bv.to_bools(), vec!(true, false, true, false,
+ /// false, false, false, false));
+ /// ```
+ pub fn to_bools(&self) -> Vec<bool> {
+ Vec::from_fn(self.nbits, |i| self.get(i))
+ }
+
+ /// Compares a `Bitv` to a slice of `bool`s.
+ /// Both the `Bitv` and slice must have the same length.
+ ///
+ /// # Failure
+ ///
+ /// Fails if the the `Bitv` and slice are of different length.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::bitv;
+ ///
+ /// let bv = bitv::from_bytes([0b10100000]);
+ ///
+ /// assert!(bv.eq_vec([true, false, true, false,
+ /// false, false, false, false]));
+ /// ```
+ pub fn eq_vec(&self, v: &[bool]) -> bool {
+ assert_eq!(self.nbits, v.len());
+ let mut i = 0;
+ while i < self.nbits {
+ if self.get(i) != v[i] { return false; }
+ i = i + 1;
+ }
+ true
+ }
+
+ /// Shortens a `Bitv`, dropping excess elements.
+ ///
+ /// If `len` is greater than the vector's current length, this has no
+ /// effect.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::bitv;
+ ///
+ /// let mut bv = bitv::from_bytes([0b01001011]);
+ /// bv.truncate(2);
+ /// assert!(bv.eq_vec([false, true]));
+ /// ```
+ pub fn truncate(&mut self, len: uint) {
+ if len < self.len() {
+ self.nbits = len;
+ let word_len = (len + u32::BITS - 1) / u32::BITS;
+ self.storage.truncate(word_len);
+ if len % u32::BITS > 0 {
+ let mask = (1 << len % u32::BITS) - 1;
+ self.storage[word_len - 1] &= mask;
+ }
+ }
+ }
+
+ /// Grows the vector to be able to store `size` bits without resizing.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::Bitv;
+ ///
+ /// let mut bv = Bitv::with_capacity(3, false);
+ /// bv.reserve(10);
+ /// assert_eq!(bv.len(), 3);
+ /// assert!(bv.capacity() >= 10);
+ /// ```
+ pub fn reserve(&mut self, size: uint) {
+ let old_size = self.storage.len();
+ let new_size = (size + u32::BITS - 1) / u32::BITS;
+ if old_size < new_size {
+ self.storage.grow(new_size - old_size, 0);
+ }
+ }
+
+ /// Returns the capacity in bits for this bit vector. Inserting any
+ /// element less than this amount will not trigger a resizing.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::Bitv;
+ ///
+ /// let mut bv = Bitv::new();
+ /// bv.reserve(10);
+ /// assert!(bv.capacity() >= 10);
+ /// ```
+ #[inline]
+ pub fn capacity(&self) -> uint {
+ self.storage.len() * u32::BITS
+ }
+
+ /// Grows the `Bitv` in-place, adding `n` copies of `value` to the `Bitv`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::bitv;
+ ///
+ /// let mut bv = bitv::from_bytes([0b01001011]);
+ /// bv.grow(2, true);
+ /// assert_eq!(bv.len(), 10);
+ /// assert_eq!(bv.to_bytes(), vec!(0b01001011, 0b11000000));
+ /// ```
+ pub fn grow(&mut self, n: uint, value: bool) {
+ let new_nbits = self.nbits + n;
+ let new_nwords = (new_nbits + u32::BITS - 1) / u32::BITS;
+ let full_value = if value { !0 } else { 0 };
+ // Correct the old tail word
+ let old_last_word = (self.nbits + u32::BITS - 1) / u32::BITS - 1;
+ if self.nbits % u32::BITS > 0 {
+ let overhang = self.nbits % u32::BITS; // # of already-used bits
+ let mask = !((1 << overhang) - 1); // e.g. 5 unused bits => 111110....0
+ if value {
+ self.storage[old_last_word] |= mask;
+ } else {
+ self.storage[old_last_word] &= !mask;
+ }
+ }
+ // Fill in words after the old tail word
+ let stop_idx = cmp::min(self.storage.len(), new_nwords);
+ for idx in range(old_last_word + 1, stop_idx) {
+ self.storage[idx] = full_value;
+ }
+ // Allocate new words, if needed
+ if new_nwords > self.storage.len() {
+ let to_add = new_nwords - self.storage.len();
+ self.storage.grow(to_add, full_value);
+
+ // Zero out and unused bits in the new tail word
+ if value {
+ let tail_word = new_nwords - 1;
+ let used_bits = new_nbits % u32::BITS;
+ self.storage[tail_word] &= (1 << used_bits) - 1;
+ }
+ }
+ // Adjust internal bit count
+ self.nbits = new_nbits;
+ }
+
+ /// Shortens by one element and returns the removed element.
+ ///
+ /// # Failure
+ ///
+ /// Assert if empty.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::bitv;
+ ///
+ /// let mut bv = bitv::from_bytes([0b01001001]);
+ /// assert_eq!(bv.pop(), true);
+ /// assert_eq!(bv.pop(), false);
+ /// assert_eq!(bv.len(), 6);
+ /// assert_eq!(bv.to_bytes(), vec!(0b01001000));
+ /// ```
+ pub fn pop(&mut self) -> bool {
+ let ret = self.get(self.nbits - 1);
+ // If we are unusing a whole word, make sure it is zeroed out
+ if self.nbits % u32::BITS == 1 {
+ self.storage[self.nbits / u32::BITS] = 0;
+ }
+ self.nbits -= 1;
+ ret
+ }
+
+ /// Pushes a `bool` onto the end.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::Bitv;
+ ///
+ /// let mut bv = Bitv::new();
+ /// bv.push(true);
+ /// bv.push(false);
+ /// assert!(bv.eq_vec([true, false]));
+ /// ```
+ pub fn push(&mut self, elem: bool) {
+ let insert_pos = self.nbits;
+ self.nbits += 1;
+ if self.storage.len() * u32::BITS < self.nbits {
+ self.storage.push(0);
+ }
+ self.set(insert_pos, elem);
+ }
+
+ /// Return the total number of bits in this vector
+ #[inline]
+ pub fn len(&self) -> uint { self.nbits }
+
+ /// Returns true if there are no bits in this vector
+ #[inline]
+ pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+ /// Clears all bits in this vector.
+ #[inline]
+ pub fn clear(&mut self) {
+ for w in self.storage.iter_mut() { *w = 0u32; }
+ }
+}
+
+/// Transforms a byte-vector into a `Bitv`. Each byte becomes eight bits,
+/// with the most significant bits of each byte coming first. Each
+/// bit becomes `true` if equal to 1 or `false` if equal to 0.
+///
+/// # Example
+///
+/// ```
+/// use std::collections::bitv;
+///
+/// let bv = bitv::from_bytes([0b10100000, 0b00010010]);
+/// assert!(bv.eq_vec([true, false, true, false,
+/// false, false, false, false,
+/// false, false, false, true,
+/// false, false, true, false]));
+/// ```
+pub fn from_bytes(bytes: &[u8]) -> Bitv {
+ from_fn(bytes.len() * 8, |i| {
+ let b = bytes[i / 8] as u32;
+ let offset = i % 8;
+ b >> (7 - offset) & 1 == 1
+ })
+}
+
+/// Creates a `Bitv` of the specified length where the value at each
+/// index is `f(index)`.
+///
+/// # Example
+///
+/// ```
+/// use std::collections::bitv::from_fn;
+///
+/// let bv = from_fn(5, |i| { i % 2 == 0 });
+/// assert!(bv.eq_vec([true, false, true, false, true]));
+/// ```
+pub fn from_fn(len: uint, f: |index: uint| -> bool) -> Bitv {
+ let mut bitv = Bitv::with_capacity(len, false);
+ for i in range(0u, len) {
+ bitv.set(i, f(i));
+ }
+ bitv
+}
+
+impl Default for Bitv {
+ #[inline]
+ fn default() -> Bitv { Bitv::new() }
+}
+
+impl FromIterator<bool> for Bitv {
+ fn from_iter<I:Iterator<bool>>(iterator: I) -> Bitv {
+ let mut ret = Bitv::new();
+ ret.extend(iterator);
+ ret
+ }
+}
+
+impl Extendable<bool> for Bitv {
+ #[inline]
+ fn extend<I: Iterator<bool>>(&mut self, mut iterator: I) {
+ let (min, _) = iterator.size_hint();
+ let nbits = self.nbits;
+ self.reserve(nbits + min);
+ for element in iterator {
+ self.push(element)
+ }
+ }
+}
+
+impl Clone for Bitv {
+ #[inline]
+ fn clone(&self) -> Bitv {
+ Bitv { storage: self.storage.clone(), nbits: self.nbits }
+ }
+
+ #[inline]
+ fn clone_from(&mut self, source: &Bitv) {
+ self.nbits = source.nbits;
+ self.storage.reserve(source.storage.len());
+ for (i, w) in self.storage.iter_mut().enumerate() { *w = source.storage[i]; }
+ }
+}
+
+impl PartialOrd for Bitv {
+ #[inline]
+ fn partial_cmp(&self, other: &Bitv) -> Option<Ordering> {
+ iter::order::partial_cmp(self.iter(), other.iter())
+ }
+}
+
+impl Ord for Bitv {
+ #[inline]
+ fn cmp(&self, other: &Bitv) -> Ordering {
+ iter::order::cmp(self.iter(), other.iter())
+ }
+}
+
+impl fmt::Show for Bitv {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ for bit in self.iter() {
+ try!(write!(fmt, "{}", if bit { 1u } else { 0u }));
+ }
+ Ok(())
+ }
+}
+
+impl<S: hash::Writer> hash::Hash<S> for Bitv {
+ fn hash(&self, state: &mut S) {
+ self.nbits.hash(state);
+ for (_, elem) in self.mask_words(0) {
+ elem.hash(state);
+ }
+ }
+}
+
+impl cmp::PartialEq for Bitv {
+ #[inline]
+ fn eq(&self, other: &Bitv) -> bool {
+ if self.nbits != other.nbits {
+ return false;
+ }
+ self.mask_words(0).zip(other.mask_words(0)).all(|((_, w1), (_, w2))| w1 == w2)
+ }
+}
+
+impl cmp::Eq for Bitv {}
+
+/// An iterator for `Bitv`.
+pub struct Bits<'a> {
+ bitv: &'a Bitv,
+ next_idx: uint,
+ end_idx: uint,
+}
+
+impl<'a> Iterator<bool> for Bits<'a> {
+ #[inline]
+ fn next(&mut self) -> Option<bool> {
+ if self.next_idx != self.end_idx {
+ let idx = self.next_idx;
+ self.next_idx += 1;
+ Some(self.bitv.get(idx))
+ } else {
+ None
+ }
+ }
+
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ let rem = self.end_idx - self.next_idx;
+ (rem, Some(rem))
+ }
+}
+
+impl<'a> DoubleEndedIterator<bool> for Bits<'a> {
+ #[inline]
+ fn next_back(&mut self) -> Option<bool> {
+ if self.next_idx != self.end_idx {
+ self.end_idx -= 1;
+ Some(self.bitv.get(self.end_idx))
+ } else {
+ None
+ }
+ }
+}
+
+impl<'a> ExactSize<bool> for Bits<'a> {}
+
+impl<'a> RandomAccessIterator<bool> for Bits<'a> {
+ #[inline]
+ fn indexable(&self) -> uint {
+ self.end_idx - self.next_idx
+ }
+
+ #[inline]
+ fn idx(&mut self, index: uint) -> Option<bool> {
+ if index >= self.indexable() {
+ None
+ } else {
+ Some(self.bitv.get(index))
+ }
+ }
+}
+
+/// An implementation of a set using a bit vector as an underlying
+/// representation for holding unsigned numerical elements.
+///
+/// It should also be noted that the amount of storage necessary for holding a
+/// set of objects is proportional to the maximum of the objects when viewed
+/// as a `uint`.
+///
+/// # Example
+///
+/// ```
+/// use std::collections::{BitvSet, Bitv};
+/// use std::collections::bitv;
+///
+/// // It's a regular set
+/// let mut s = BitvSet::new();
+/// s.insert(0);
+/// s.insert(3);
+/// s.insert(7);
+///
+/// s.remove(&7);
+///
+/// if !s.contains(&7) {
+/// println!("There is no 7");
+/// }
+///
+/// // Can initialize from a `Bitv`
+/// let other = BitvSet::from_bitv(bitv::from_bytes([0b11010000]));
+///
+/// s.union_with(&other);
+///
+/// // Print 0, 1, 3 in some order
+/// for x in s.iter() {
+/// println!("{}", x);
+/// }
+///
+/// // Can convert back to a `Bitv`
+/// let bv: Bitv = s.into_bitv();
+/// assert!(bv.get(3));
+/// ```
+#[deriving(Clone)]
+pub struct BitvSet(Bitv);
+
+impl Default for BitvSet {
+ #[inline]
+ fn default() -> BitvSet { BitvSet::new() }
+}
+
+impl FromIterator<bool> for BitvSet {
+ fn from_iter<I:Iterator<bool>>(iterator: I) -> BitvSet {
+ let mut ret = BitvSet::new();
+ ret.extend(iterator);
+ ret
+ }
+}
+
+impl Extendable<bool> for BitvSet {
+ #[inline]
+ fn extend<I: Iterator<bool>>(&mut self, iterator: I) {
+ let &BitvSet(ref mut self_bitv) = self;
+ self_bitv.extend(iterator);
+ }
+}
+
+impl PartialOrd for BitvSet {
+ #[inline]
+ fn partial_cmp(&self, other: &BitvSet) -> Option<Ordering> {
+ let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref());
+ iter::order::partial_cmp(a_iter, b_iter)
+ }
+}
+
+impl Ord for BitvSet {
+ #[inline]
+ fn cmp(&self, other: &BitvSet) -> Ordering {
+ let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref());
+ iter::order::cmp(a_iter, b_iter)
+ }
+}
+
+impl cmp::PartialEq for BitvSet {
+ #[inline]
+ fn eq(&self, other: &BitvSet) -> bool {
+ let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref());
+ iter::order::eq(a_iter, b_iter)
+ }
+}
+
+impl cmp::Eq for BitvSet {}
+
+impl BitvSet {
+ /// Creates a new bit vector set with initially no contents.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BitvSet;
+ /// let mut s = BitvSet::new();
+ /// ```
+ #[inline]
+ pub fn new() -> BitvSet {
+ BitvSet(Bitv::new())
+ }
+
+ /// Creates a new bit vector set with initially no contents, able to
+ /// hold `nbits` elements without resizing.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BitvSet;
+ /// let mut s = BitvSet::with_capacity(100);
+ /// assert!(s.capacity() >= 100);
+ /// ```
+ #[inline]
+ pub fn with_capacity(nbits: uint) -> BitvSet {
+ let bitv = Bitv::with_capacity(nbits, false);
+ BitvSet::from_bitv(bitv)
+ }
+
+ /// Creates a new bit vector set from the given bit vector.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::{bitv, BitvSet};
+ ///
+ /// let bv = bitv::from_bytes([0b01100000]);
+ /// let s = BitvSet::from_bitv(bv);
+ ///
+ /// // Print 1, 2 in arbitrary order
+ /// for x in s.iter() {
+ /// println!("{}", x);
+ /// }
+ /// ```
+ #[inline]
+ pub fn from_bitv(mut bitv: Bitv) -> BitvSet {
+ // Mark every bit as valid
+ bitv.nbits = bitv.capacity();
+ BitvSet(bitv)
+ }
+
+ /// Returns the capacity in bits for this bit vector. Inserting any
+ /// element less than this amount will not trigger a resizing.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BitvSet;
+ ///
+ /// let mut s = BitvSet::with_capacity(100);
+ /// assert!(s.capacity() >= 100);
+ /// ```
+ #[inline]
+ pub fn capacity(&self) -> uint {
+ let &BitvSet(ref bitv) = self;
+ bitv.capacity()
+ }
+
+ /// Grows the underlying vector to be able to store `size` bits.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BitvSet;
+ ///
+ /// let mut s = BitvSet::new();
+ /// s.reserve(10);
+ /// assert!(s.capacity() >= 10);
+ /// ```
+ pub fn reserve(&mut self, size: uint) {
+ let &BitvSet(ref mut bitv) = self;
+ bitv.reserve(size);
+ if bitv.nbits < size {
+ bitv.nbits = bitv.capacity();
+ }
+ }
+
+ /// Consumes this set to return the underlying bit vector.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BitvSet;
+ ///
+ /// let mut s = BitvSet::new();
+ /// s.insert(0);
+ /// s.insert(3);
+ ///
+ /// let bv = s.into_bitv();
+ /// assert!(bv.get(0));
+ /// assert!(bv.get(3));
+ /// ```
+ #[inline]
+ pub fn into_bitv(self) -> Bitv {
+ let BitvSet(bitv) = self;
+ bitv
+ }
+
+ /// Returns a reference to the underlying bit vector.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BitvSet;
+ ///
+ /// let mut s = BitvSet::new();
+ /// s.insert(0);
+ ///
+ /// let bv = s.get_ref();
+ /// assert_eq!(bv[0], true);
+ /// ```
+ #[inline]
+ pub fn get_ref<'a>(&'a self) -> &'a Bitv {
+ let &BitvSet(ref bitv) = self;
+ bitv
+ }
+
+ #[inline]
+ fn other_op(&mut self, other: &BitvSet, f: |u32, u32| -> u32) {
+ // Expand the vector if necessary
+ self.reserve(other.capacity());
+
+ // Unwrap Bitvs
+ let &BitvSet(ref mut self_bitv) = self;
+ let &BitvSet(ref other_bitv) = other;
+
+ // virtually pad other with 0's for equal lengths
+ let mut other_words = {
+ let (_, result) = match_words(self_bitv, other_bitv);
+ result
+ };
+
+ // Apply values found in other
+ for (i, w) in other_words {
+ let old = self_bitv.storage[i];
+ let new = f(old, w);
+ self_bitv.storage[i] = new;
+ }
+ }
+
+ /// Truncates the underlying vector to the least length required.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BitvSet;
+ ///
+ /// let mut s = BitvSet::new();
+ /// s.insert(32183231);
+ /// s.remove(&32183231);
+ ///
+ /// // Internal storage will probably be bigger than necessary
+ /// println!("old capacity: {}", s.capacity());
+ ///
+ /// // Now should be smaller
+ /// s.shrink_to_fit();
+ /// println!("new capacity: {}", s.capacity());
+ /// ```
+ #[inline]
+ pub fn shrink_to_fit(&mut self) {
+ let &BitvSet(ref mut bitv) = self;
+ // Obtain original length
+ let old_len = bitv.storage.len();
+ // Obtain coarse trailing zero length
+ let n = bitv.storage.iter().rev().take_while(|&&n| n == 0).count();
+ // Truncate
+ let trunc_len = cmp::max(old_len - n, 1);
+ bitv.storage.truncate(trunc_len);
+ bitv.nbits = trunc_len * u32::BITS;
+ }
+
+ /// Iterator over each u32 stored in the `BitvSet`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BitvSet;
+ /// use std::collections::bitv;
+ ///
+ /// let s = BitvSet::from_bitv(bitv::from_bytes([0b01001010]));
+ ///
+ /// // Print 1, 4, 6 in arbitrary order
+ /// for x in s.iter() {
+ /// println!("{}", x);
+ /// }
+ /// ```
+ #[inline]
+ pub fn iter<'a>(&'a self) -> BitPositions<'a> {
+ BitPositions {set: self, next_idx: 0u}
+ }
+
+ /// Iterator over each u32 stored in `self` union `other`.
+ /// See [union_with](#method.union_with) for an efficient in-place version.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BitvSet;
+ /// use std::collections::bitv;
+ ///
+ /// let a = BitvSet::from_bitv(bitv::from_bytes([0b01101000]));
+ /// let b = BitvSet::from_bitv(bitv::from_bytes([0b10100000]));
+ ///
+ /// // Print 0, 1, 2, 4 in arbitrary order
+ /// for x in a.union(&b) {
+ /// println!("{}", x);
+ /// }
+ /// ```
+ #[inline]
+ pub fn union<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
+ TwoBitPositions {
+ set: self,
+ other: other,
+ merge: |w1, w2| w1 | w2,
+ current_word: 0u32,
+ next_idx: 0u
+ }
+ }
+
+ /// Iterator over each uint stored in `self` intersect `other`.
+ /// See [intersect_with](#method.intersect_with) for an efficient in-place version.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BitvSet;
+ /// use std::collections::bitv;
+ ///
+ /// let a = BitvSet::from_bitv(bitv::from_bytes([0b01101000]));
+ /// let b = BitvSet::from_bitv(bitv::from_bytes([0b10100000]));
+ ///
+ /// // Print 2
+ /// for x in a.intersection(&b) {
+ /// println!("{}", x);
+ /// }
+ /// ```
+ #[inline]
+ pub fn intersection<'a>(&'a self, other: &'a BitvSet) -> Take<TwoBitPositions<'a>> {
+ let min = cmp::min(self.capacity(), other.capacity());
+ TwoBitPositions {
+ set: self,
+ other: other,
+ merge: |w1, w2| w1 & w2,
+ current_word: 0u32,
+ next_idx: 0
+ }.take(min)
+ }
+
+ /// Iterator over each uint stored in the `self` setminus `other`.
+ /// See [difference_with](#method.difference_with) for an efficient in-place version.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BitvSet;
+ /// use std::collections::bitv;
+ ///
+ /// let a = BitvSet::from_bitv(bitv::from_bytes([0b01101000]));
+ /// let b = BitvSet::from_bitv(bitv::from_bytes([0b10100000]));
+ ///
+ /// // Print 1, 4 in arbitrary order
+ /// for x in a.difference(&b) {
+ /// println!("{}", x);
+ /// }
+ ///
+ /// // Note that difference is not symmetric,
+ /// // and `b - a` means something else.
+ /// // This prints 0
+ /// for x in b.difference(&a) {
+ /// println!("{}", x);
+ /// }
+ /// ```
+ #[inline]
+ pub fn difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
+ TwoBitPositions {
+ set: self,
+ other: other,
+ merge: |w1, w2| w1 & !w2,
+ current_word: 0u32,
+ next_idx: 0
+ }
+ }
+
+ /// Iterator over each u32 stored in the symmetric difference of `self` and `other`.
+ /// See [symmetric_difference_with](#method.symmetric_difference_with) for
+ /// an efficient in-place version.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BitvSet;
+ /// use std::collections::bitv;
+ ///
+ /// let a = BitvSet::from_bitv(bitv::from_bytes([0b01101000]));
+ /// let b = BitvSet::from_bitv(bitv::from_bytes([0b10100000]));
+ ///
+ /// // Print 0, 1, 4 in arbitrary order
+ /// for x in a.symmetric_difference(&b) {
+ /// println!("{}", x);
+ /// }
+ /// ```
+ #[inline]
+ pub fn symmetric_difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
+ TwoBitPositions {
+ set: self,
+ other: other,
+ merge: |w1, w2| w1 ^ w2,
+ current_word: 0u32,
+ next_idx: 0
+ }
+ }
+
+ /// Unions in-place with the specified other bit vector.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BitvSet;
+ /// use std::collections::bitv;
+ ///
+ /// let a = 0b01101000;
+ /// let b = 0b10100000;
+ /// let res = 0b11101000;
+ ///
+ /// let mut a = BitvSet::from_bitv(bitv::from_bytes([a]));
+ /// let b = BitvSet::from_bitv(bitv::from_bytes([b]));
+ /// let res = BitvSet::from_bitv(bitv::from_bytes([res]));
+ ///
+ /// a.union_with(&b);
+ /// assert_eq!(a, res);
+ /// ```
+ #[inline]
+ pub fn union_with(&mut self, other: &BitvSet) {
+ self.other_op(other, |w1, w2| w1 | w2);
+ }
+
+ /// Intersects in-place with the specified other bit vector.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BitvSet;
+ /// use std::collections::bitv;
+ ///
+ /// let a = 0b01101000;
+ /// let b = 0b10100000;
+ /// let res = 0b00100000;
+ ///
+ /// let mut a = BitvSet::from_bitv(bitv::from_bytes([a]));
+ /// let b = BitvSet::from_bitv(bitv::from_bytes([b]));
+ /// let res = BitvSet::from_bitv(bitv::from_bytes([res]));
+ ///
+ /// a.intersect_with(&b);
+ /// assert_eq!(a, res);
+ /// ```
+ #[inline]
+ pub fn intersect_with(&mut self, other: &BitvSet) {
+ self.other_op(other, |w1, w2| w1 & w2);
+ }
+
+ /// Makes this bit vector the difference with the specified other bit vector
+ /// in-place.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BitvSet;
+ /// use std::collections::bitv;
+ ///
+ /// let a = 0b01101000;
+ /// let b = 0b10100000;
+ /// let a_b = 0b01001000; // a - b
+ /// let b_a = 0b10000000; // b - a
+ ///
+ /// let mut bva = BitvSet::from_bitv(bitv::from_bytes([a]));
+ /// let bvb = BitvSet::from_bitv(bitv::from_bytes([b]));
+ /// let bva_b = BitvSet::from_bitv(bitv::from_bytes([a_b]));
+ /// let bvb_a = BitvSet::from_bitv(bitv::from_bytes([b_a]));
+ ///
+ /// bva.difference_with(&bvb);
+ /// assert_eq!(bva, bva_b);
+ ///
+ /// let bva = BitvSet::from_bitv(bitv::from_bytes([a]));
+ /// let mut bvb = BitvSet::from_bitv(bitv::from_bytes([b]));
+ ///
+ /// bvb.difference_with(&bva);
+ /// assert_eq!(bvb, bvb_a);
+ /// ```
+ #[inline]
+ pub fn difference_with(&mut self, other: &BitvSet) {
+ self.other_op(other, |w1, w2| w1 & !w2);
+ }
+
+ /// Makes this bit vector the symmetric difference with the specified other
+ /// bit vector in-place.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BitvSet;
+ /// use std::collections::bitv;
+ ///
+ /// let a = 0b01101000;
+ /// let b = 0b10100000;
+ /// let res = 0b11001000;
+ ///
+ /// let mut a = BitvSet::from_bitv(bitv::from_bytes([a]));
+ /// let b = BitvSet::from_bitv(bitv::from_bytes([b]));
+ /// let res = BitvSet::from_bitv(bitv::from_bytes([res]));
+ ///
+ /// a.symmetric_difference_with(&b);
+ /// assert_eq!(a, res);
+ /// ```
+ #[inline]
+ pub fn symmetric_difference_with(&mut self, other: &BitvSet) {
+ self.other_op(other, |w1, w2| w1 ^ w2);
+ }
+
+ /// Return the number of set bits in this set.
+ #[inline]
+ pub fn len(&self) -> uint {
+ let &BitvSet(ref bitv) = self;
+ bitv.storage.iter().fold(0, |acc, &n| acc + n.count_ones())
+ }
+
+ /// Returns whether there are no bits set in this set
+ #[inline]
+ pub fn is_empty(&self) -> bool {
+ let &BitvSet(ref bitv) = self;
+ bitv.storage.iter().all(|&n| n == 0)
+ }
+
+ /// Clears all bits in this set
+ #[inline]
+ pub fn clear(&mut self) {
+ let &BitvSet(ref mut bitv) = self;
+ bitv.clear();
+ }
+
+ /// Returns `true` if this set contains the specified integer.
+ #[inline]
+ pub fn contains(&self, value: &uint) -> bool {
+ let &BitvSet(ref bitv) = self;
+ *value < bitv.nbits && bitv.get(*value)
+ }
+
+ /// Returns `true` if the set has no elements in common with `other`.
+ /// This is equivalent to checking for an empty intersection.
+ #[inline]
+ pub fn is_disjoint(&self, other: &BitvSet) -> bool {
+ self.intersection(other).next().is_none()
+ }
+
+ /// Returns `true` if the set is a subset of another.
+ #[inline]
+ pub fn is_subset(&self, other: &BitvSet) -> bool {
+ let &BitvSet(ref self_bitv) = self;
+ let &BitvSet(ref other_bitv) = other;
+
+ // Check that `self` intersect `other` is self
+ self_bitv.mask_words(0).zip(other_bitv.mask_words(0))
+ .all(|((_, w1), (_, w2))| w1 & w2 == w1) &&
+ // Check that `self` setminus `other` is empty
+ self_bitv.mask_words(other_bitv.storage.len()).all(|(_, w)| w == 0)
+ }
+
+ /// Returns `true` if the set is a superset of another.
+ #[inline]
+ pub fn is_superset(&self, other: &BitvSet) -> bool {
+ other.is_subset(self)
+ }
+
+ /// Adds a value to the set. Returns `true` if the value was not already
+ /// present in the set.
+ pub fn insert(&mut self, value: uint) -> bool {
+ if self.contains(&value) {
+ return false;
+ }
+
+ // Ensure we have enough space to hold the new element
+ if value >= self.capacity() {
+ let new_cap = cmp::max(value + 1, self.capacity() * 2);
+ self.reserve(new_cap);
+ }
+
+ let &BitvSet(ref mut bitv) = self;
+ bitv.set(value, true);
+ return true;
+ }
+
+ /// Removes a value from the set. Returns `true` if the value was
+ /// present in the set.
+ pub fn remove(&mut self, value: &uint) -> bool {
+ if !self.contains(value) {
+ return false;
+ }
+ let &BitvSet(ref mut bitv) = self;
+ bitv.set(*value, false);
+ return true;
+ }
+}
+
+impl fmt::Show for BitvSet {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ try!(write!(fmt, "{{"));
+ let mut first = true;
+ for n in self.iter() {
+ if !first {
+ try!(write!(fmt, ", "));
+ }
+ try!(write!(fmt, "{}", n));
+ first = false;
+ }
+ write!(fmt, "}}")
+ }
+}
+
+impl<S: hash::Writer> hash::Hash<S> for BitvSet {
+ fn hash(&self, state: &mut S) {
+ for pos in self.iter() {
+ pos.hash(state);
+ }
+ }
+}
+
+/// An iterator for `BitvSet`.
+pub struct BitPositions<'a> {
+ set: &'a BitvSet,
+ next_idx: uint
+}
+
+/// An iterator combining two `BitvSet` iterators.
+pub struct TwoBitPositions<'a> {
+ set: &'a BitvSet,
+ other: &'a BitvSet,
+ merge: |u32, u32|: 'a -> u32,
+ current_word: u32,
+ next_idx: uint
+}
+
+impl<'a> Iterator<uint> for BitPositions<'a> {
+ fn next(&mut self) -> Option<uint> {
+ while self.next_idx < self.set.capacity() {
+ let idx = self.next_idx;
+ self.next_idx += 1;
+
+ if self.set.contains(&idx) {
+ return Some(idx);
+ }
+ }
+
+ return None;
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ (0, Some(self.set.capacity() - self.next_idx))
+ }
+}
+
+impl<'a> Iterator<uint> for TwoBitPositions<'a> {
+ fn next(&mut self) -> Option<uint> {
+ while self.next_idx < self.set.capacity() ||
+ self.next_idx < self.other.capacity() {
+ let bit_idx = self.next_idx % u32::BITS;
+ if bit_idx == 0 {
+ let &BitvSet(ref s_bitv) = self.set;
+ let &BitvSet(ref o_bitv) = self.other;
+ // Merging the two words is a bit of an awkward dance since
+ // one Bitv might be longer than the other
+ let word_idx = self.next_idx / u32::BITS;
+ let w1 = if word_idx < s_bitv.storage.len() {
+ s_bitv.storage[word_idx]
+ } else { 0 };
+ let w2 = if word_idx < o_bitv.storage.len() {
+ o_bitv.storage[word_idx]
+ } else { 0 };
+ self.current_word = (self.merge)(w1, w2);
+ }
+
+ self.next_idx += 1;
+ if self.current_word & (1 << bit_idx) != 0 {
+ return Some(self.next_idx - 1);
+ }
+ }
+ return None;
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ let cap = cmp::max(self.set.capacity(), self.other.capacity());
+ (0, Some(cap - self.next_idx))
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use std::prelude::*;
+ use std::iter::range_step;
+ use std::u32;
+ use std::rand;
+ use std::rand::Rng;
+ use test::Bencher;
+
+ use super::{Bitv, BitvSet, from_fn, from_bytes};
+ use bitv;
+ use vec::Vec;
+
+ static BENCH_BITS : uint = 1 << 14;
+
+ #[test]
+ fn test_to_str() {
+ let zerolen = Bitv::new();
+ assert_eq!(zerolen.to_string().as_slice(), "");
+
+ let eightbits = Bitv::with_capacity(8u, false);
+ assert_eq!(eightbits.to_string().as_slice(), "00000000")
+ }
+
+ #[test]
+ fn test_0_elements() {
+ let act = Bitv::new();
+ let exp = Vec::from_elem(0u, false);
+ assert!(act.eq_vec(exp.as_slice()));
+ }
+
+ #[test]
+ fn test_1_element() {
+ let mut act = Bitv::with_capacity(1u, false);
+ assert!(act.eq_vec([false]));
+ act = Bitv::with_capacity(1u, true);
+ assert!(act.eq_vec([true]));
+ }
+
+ #[test]
+ fn test_2_elements() {
+ let mut b = bitv::Bitv::with_capacity(2, false);
+ b.set(0, true);
+ b.set(1, false);
+ assert_eq!(b.to_string().as_slice(), "10");
+ }
+
+ #[test]
+ fn test_10_elements() {
+ let mut act;
+ // all 0
+
+ act = Bitv::with_capacity(10u, false);
+ assert!((act.eq_vec(
+ [false, false, false, false, false, false, false, false, false, false])));
+ // all 1
+
+ act = Bitv::with_capacity(10u, true);
+ assert!((act.eq_vec([true, true, true, true, true, true, true, true, true, true])));
+ // mixed
+
+ act = Bitv::with_capacity(10u, false);
+ act.set(0u, true);
+ act.set(1u, true);
+ act.set(2u, true);
+ act.set(3u, true);
+ act.set(4u, true);
+ assert!((act.eq_vec([true, true, true, true, true, false, false, false, false, false])));
+ // mixed
+
+ act = Bitv::with_capacity(10u, false);
+ act.set(5u, true);
+ act.set(6u, true);
+ act.set(7u, true);
+ act.set(8u, true);
+ act.set(9u, true);
+ assert!((act.eq_vec([false, false, false, false, false, true, true, true, true, true])));
+ // mixed
+
+ act = Bitv::with_capacity(10u, false);
+ act.set(0u, true);
+ act.set(3u, true);
+ act.set(6u, true);
+ act.set(9u, true);
+ assert!((act.eq_vec([true, false, false, true, false, false, true, false, false, true])));
+ }
+
+ #[test]
+ fn test_31_elements() {
+ let mut act;
+ // all 0
+
+ act = Bitv::with_capacity(31u, false);
+ assert!(act.eq_vec(
+ [false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false]));
+ // all 1
+
+ act = Bitv::with_capacity(31u, true);
+ assert!(act.eq_vec(
+ [true, true, true, true, true, true, true, true, true, true, true, true, true,
+ true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+ true, true, true, true]));
+ // mixed
+
+ act = Bitv::with_capacity(31u, false);
+ act.set(0u, true);
+ act.set(1u, true);
+ act.set(2u, true);
+ act.set(3u, true);
+ act.set(4u, true);
+ act.set(5u, true);
+ act.set(6u, true);
+ act.set(7u, true);
+ assert!(act.eq_vec(
+ [true, true, true, true, true, true, true, true, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false]));
+ // mixed
+
+ act = Bitv::with_capacity(31u, false);
+ act.set(16u, true);
+ act.set(17u, true);
+ act.set(18u, true);
+ act.set(19u, true);
+ act.set(20u, true);
+ act.set(21u, true);
+ act.set(22u, true);
+ act.set(23u, true);
+ assert!(act.eq_vec(
+ [false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, true, true, true, true, true, true, true, true,
+ false, false, false, false, false, false, false]));
+ // mixed
+
+ act = Bitv::with_capacity(31u, false);
+ act.set(24u, true);
+ act.set(25u, true);
+ act.set(26u, true);
+ act.set(27u, true);
+ act.set(28u, true);
+ act.set(29u, true);
+ act.set(30u, true);
+ assert!(act.eq_vec(
+ [false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false, false, false,
+ false, true, true, true, true, true, true, true]));
+ // mixed
+
+ act = Bitv::with_capacity(31u, false);
+ act.set(3u, true);
+ act.set(17u, true);
+ act.set(30u, true);
+ assert!(act.eq_vec(
+ [false, false, false, true, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, true, false, false, false, false, false, false,
+ false, false, false, false, false, false, true]));
+ }
+
+ #[test]
+ fn test_32_elements() {
+ let mut act;
+ // all 0
+
+ act = Bitv::with_capacity(32u, false);
+ assert!(act.eq_vec(
+ [false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false]));
+ // all 1
+
+ act = Bitv::with_capacity(32u, true);
+ assert!(act.eq_vec(
+ [true, true, true, true, true, true, true, true, true, true, true, true, true,
+ true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+ true, true, true, true, true]));
+ // mixed
+
+ act = Bitv::with_capacity(32u, false);
+ act.set(0u, true);
+ act.set(1u, true);
+ act.set(2u, true);
+ act.set(3u, true);
+ act.set(4u, true);
+ act.set(5u, true);
+ act.set(6u, true);
+ act.set(7u, true);
+ assert!(act.eq_vec(
+ [true, true, true, true, true, true, true, true, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false]));
+ // mixed
+
+ act = Bitv::with_capacity(32u, false);
+ act.set(16u, true);
+ act.set(17u, true);
+ act.set(18u, true);
+ act.set(19u, true);
+ act.set(20u, true);
+ act.set(21u, true);
+ act.set(22u, true);
+ act.set(23u, true);
+ assert!(act.eq_vec(
+ [false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, true, true, true, true, true, true, true, true,
+ false, false, false, false, false, false, false, false]));
+ // mixed
+
+ act = Bitv::with_capacity(32u, false);
+ act.set(24u, true);
+ act.set(25u, true);
+ act.set(26u, true);
+ act.set(27u, true);
+ act.set(28u, true);
+ act.set(29u, true);
+ act.set(30u, true);
+ act.set(31u, true);
+ assert!(act.eq_vec(
+ [false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false, false, false,
+ false, true, true, true, true, true, true, true, true]));
+ // mixed
+
+ act = Bitv::with_capacity(32u, false);
+ act.set(3u, true);
+ act.set(17u, true);
+ act.set(30u, true);
+ act.set(31u, true);
+ assert!(act.eq_vec(
+ [false, false, false, true, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, true, false, false, false, false, false, false,
+ false, false, false, false, false, false, true, true]));
+ }
+
+ #[test]
+ fn test_33_elements() {
+ let mut act;
+ // all 0
+
+ act = Bitv::with_capacity(33u, false);
+ assert!(act.eq_vec(
+ [false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false]));
+ // all 1
+
+ act = Bitv::with_capacity(33u, true);
+ assert!(act.eq_vec(
+ [true, true, true, true, true, true, true, true, true, true, true, true, true,
+ true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+ true, true, true, true, true, true]));
+ // mixed
+
+ act = Bitv::with_capacity(33u, false);
+ act.set(0u, true);
+ act.set(1u, true);
+ act.set(2u, true);
+ act.set(3u, true);
+ act.set(4u, true);
+ act.set(5u, true);
+ act.set(6u, true);
+ act.set(7u, true);
+ assert!(act.eq_vec(
+ [true, true, true, true, true, true, true, true, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false]));
+ // mixed
+
+ act = Bitv::with_capacity(33u, false);
+ act.set(16u, true);
+ act.set(17u, true);
+ act.set(18u, true);
+ act.set(19u, true);
+ act.set(20u, true);
+ act.set(21u, true);
+ act.set(22u, true);
+ act.set(23u, true);
+ assert!(act.eq_vec(
+ [false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, true, true, true, true, true, true, true, true,
+ false, false, false, false, false, false, false, false, false]));
+ // mixed
+
+ act = Bitv::with_capacity(33u, false);
+ act.set(24u, true);
+ act.set(25u, true);
+ act.set(26u, true);
+ act.set(27u, true);
+ act.set(28u, true);
+ act.set(29u, true);
+ act.set(30u, true);
+ act.set(31u, true);
+ assert!(act.eq_vec(
+ [false, false, false, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false, false, false, false, false,
+ false, true, true, true, true, true, true, true, true, false]));
+ // mixed
+
+ act = Bitv::with_capacity(33u, false);
+ act.set(3u, true);
+ act.set(17u, true);
+ act.set(30u, true);
+ act.set(31u, true);
+ act.set(32u, true);
+ assert!(act.eq_vec(
+ [false, false, false, true, false, false, false, false, false, false, false, false,
+ false, false, false, false, false, true, false, false, false, false, false, false,
+ false, false, false, false, false, false, true, true, true]));
+ }
+
+ #[test]
+ fn test_equal_differing_sizes() {
+ let v0 = Bitv::with_capacity(10u, false);
+ let v1 = Bitv::with_capacity(11u, false);
+ assert!(v0 != v1);
+ }
+
+ #[test]
+ fn test_equal_greatly_differing_sizes() {
+ let v0 = Bitv::with_capacity(10u, false);
+ let v1 = Bitv::with_capacity(110u, false);
+ assert!(v0 != v1);
+ }
+
+ #[test]
+ fn test_equal_sneaky_small() {
+ let mut a = bitv::Bitv::with_capacity(1, false);
+ a.set(0, true);
+
+ let mut b = bitv::Bitv::with_capacity(1, true);
+ b.set(0, true);
+
+ assert_eq!(a, b);
+ }
+
+ #[test]
+ fn test_equal_sneaky_big() {
+ let mut a = bitv::Bitv::with_capacity(100, false);
+ for i in range(0u, 100) {
+ a.set(i, true);
+ }
+
+ let mut b = bitv::Bitv::with_capacity(100, true);
+ for i in range(0u, 100) {
+ b.set(i, true);
+ }
+
+ assert_eq!(a, b);
+ }
+
+ #[test]
+ fn test_from_bytes() {
+ let bitv = from_bytes([0b10110110, 0b00000000, 0b11111111]);
+ let str = format!("{}{}{}", "10110110", "00000000", "11111111");
+ assert_eq!(bitv.to_string().as_slice(), str.as_slice());
+ }
+
+ #[test]
+ fn test_to_bytes() {
+ let mut bv = Bitv::with_capacity(3, true);
+ bv.set(1, false);
+ assert_eq!(bv.to_bytes(), vec!(0b10100000));
+
+ let mut bv = Bitv::with_capacity(9, false);
+ bv.set(2, true);
+ bv.set(8, true);
+ assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000));
+ }
+
+ #[test]
+ fn test_from_bools() {
+ let bools = vec![true, false, true, true];
+ let bitv: Bitv = bools.iter().map(|n| *n).collect();
+ assert_eq!(bitv.to_string().as_slice(), "1011");
+ }
+
+ #[test]
+ fn test_bitv_set_from_bools() {
+ let bools = vec![true, false, true, true];
+ let a: BitvSet = bools.iter().map(|n| *n).collect();
+ let mut b = BitvSet::new();
+ b.insert(0);
+ b.insert(2);
+ b.insert(3);
+ assert_eq!(a, b);
+ }
+
+ #[test]
+ fn test_to_bools() {
+ let bools = vec!(false, false, true, false, false, true, true, false);
+ assert_eq!(from_bytes([0b00100110]).iter().collect::<Vec<bool>>(), bools);
+ }
+
+ #[test]
+ fn test_bitv_iterator() {
+ let bools = vec![true, false, true, true];
+ let bitv: Bitv = bools.iter().map(|n| *n).collect();
+
+ assert_eq!(bitv.iter().collect::<Vec<bool>>(), bools)
+
+ let long = Vec::from_fn(10000, |i| i % 2 == 0);
+ let bitv: Bitv = long.iter().map(|n| *n).collect();
+ assert_eq!(bitv.iter().collect::<Vec<bool>>(), long)
+ }
+
+ #[test]
+ fn test_bitv_set_iterator() {
+ let bools = [true, false, true, true];
+ let bitv: BitvSet = bools.iter().map(|n| *n).collect();
+
+ let idxs: Vec<uint> = bitv.iter().collect();
+ assert_eq!(idxs, vec!(0, 2, 3));
+
+ let long: BitvSet = range(0u, 10000).map(|n| n % 2 == 0).collect();
+ let real = range_step(0, 10000, 2).collect::<Vec<uint>>();
+
+ let idxs: Vec<uint> = long.iter().collect();
+ assert_eq!(idxs, real);
+ }
+
+ #[test]
+ fn test_bitv_set_frombitv_init() {
+ let bools = [true, false];
+ let lengths = [10, 64, 100];
+ for &b in bools.iter() {
+ for &l in lengths.iter() {
+ let bitset = BitvSet::from_bitv(Bitv::with_capacity(l, b));
+ assert_eq!(bitset.contains(&1u), b)
+ assert_eq!(bitset.contains(&(l-1u)), b)
+ assert!(!bitset.contains(&l))
+ }
+ }
+ }
+
+ #[test]
+ fn test_small_difference() {
+ let mut b1 = Bitv::with_capacity(3, false);
+ let mut b2 = Bitv::with_capacity(3, false);
+ b1.set(0, true);
+ b1.set(1, true);
+ b2.set(1, true);
+ b2.set(2, true);
+ assert!(b1.difference(&b2));
+ assert!(b1.get(0));
+ assert!(!b1.get(1));
+ assert!(!b1.get(2));
+ }
+
+ #[test]
+ fn test_big_difference() {
+ let mut b1 = Bitv::with_capacity(100, false);
+ let mut b2 = Bitv::with_capacity(100, false);
+ b1.set(0, true);
+ b1.set(40, true);
+ b2.set(40, true);
+ b2.set(80, true);
+ assert!(b1.difference(&b2));
+ assert!(b1.get(0));
+ assert!(!b1.get(40));
+ assert!(!b1.get(80));
+ }
+
+ #[test]
+ fn test_small_clear() {
+ let mut b = Bitv::with_capacity(14, true);
+ b.clear();
+ assert!(b.none());
+ }
+
+ #[test]
+ fn test_big_clear() {
+ let mut b = Bitv::with_capacity(140, true);
+ b.clear();
+ assert!(b.none());
+ }
+
+ #[test]
+ fn test_bitv_masking() {
+ let b = Bitv::with_capacity(140, true);
+ let mut bs = BitvSet::from_bitv(b);
+ assert!(bs.contains(&139));
+ assert!(!bs.contains(&140));
+ assert!(bs.insert(150));
+ assert!(!bs.contains(&140));
+ assert!(!bs.contains(&149));
+ assert!(bs.contains(&150));
+ assert!(!bs.contains(&151));
+ }
+
+ #[test]
+ fn test_bitv_set_basic() {
+ // calculate nbits with u32::BITS granularity
+ fn calc_nbits(bits: uint) -> uint {
+ u32::BITS * ((bits + u32::BITS - 1) / u32::BITS)
+ }
+
+ let mut b = BitvSet::new();
+ assert_eq!(b.capacity(), calc_nbits(0));
+ assert!(b.insert(3));
+ assert_eq!(b.capacity(), calc_nbits(3));
+ assert!(!b.insert(3));
+ assert!(b.contains(&3));
+ assert!(b.insert(4));
+ assert!(!b.insert(4));
+ assert!(b.contains(&3));
+ assert!(b.insert(400));
+ assert_eq!(b.capacity(), calc_nbits(400));
+ assert!(!b.insert(400));
+ assert!(b.contains(&400));
+ assert_eq!(b.len(), 3);
+ }
+
+ #[test]
+ fn test_bitv_set_intersection() {
+ let mut a = BitvSet::new();
+ let mut b = BitvSet::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!(b.insert(2));
+ assert!(b.insert(11));
+ assert!(b.insert(77));
+ assert!(b.insert(5));
+ assert!(b.insert(3));
+
+ let expected = [3, 5, 11, 77];
+ let actual = a.intersection(&b).collect::<Vec<uint>>();
+ assert_eq!(actual.as_slice(), expected.as_slice());
+ }
+
+ #[test]
+ fn test_bitv_set_difference() {
+ let mut a = BitvSet::new();
+ let mut b = BitvSet::new();
+
+ assert!(a.insert(1));
+ assert!(a.insert(3));
+ assert!(a.insert(5));
+ assert!(a.insert(200));
+ assert!(a.insert(500));
+
+ assert!(b.insert(3));
+ assert!(b.insert(200));
+
+ let expected = [1, 5, 500];
+ let actual = a.difference(&b).collect::<Vec<uint>>();
+ assert_eq!(actual.as_slice(), expected.as_slice());
+ }
+
+ #[test]
+ fn test_bitv_set_symmetric_difference() {
+ let mut a = BitvSet::new();
+ let mut b = BitvSet::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));
+ assert!(b.insert(14));
+ assert!(b.insert(220));
+
+ let expected = [1, 5, 11, 14, 220];
+ let actual = a.symmetric_difference(&b).collect::<Vec<uint>>();
+ assert_eq!(actual.as_slice(), expected.as_slice());
+ }
+
+ #[test]
+ fn test_bitv_set_union() {
+ let mut a = BitvSet::new();
+ let mut b = BitvSet::new();
+ assert!(a.insert(1));
+ assert!(a.insert(3));
+ assert!(a.insert(5));
+ assert!(a.insert(9));
+ assert!(a.insert(11));
+ assert!(a.insert(160));
+ assert!(a.insert(19));
+ assert!(a.insert(24));
+ assert!(a.insert(200));
+
+ assert!(b.insert(1));
+ assert!(b.insert(5));
+ assert!(b.insert(9));
+ assert!(b.insert(13));
+ assert!(b.insert(19));
+
+ let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160, 200];
+ let actual = a.union(&b).collect::<Vec<uint>>();
+ assert_eq!(actual.as_slice(), expected.as_slice());
+ }
+
+ #[test]
+ fn test_bitv_set_subset() {
+ let mut set1 = BitvSet::new();
+ let mut set2 = BitvSet::new();
+
+ assert!(set1.is_subset(&set2)); // {} {}
+ set2.insert(100);
+ assert!(set1.is_subset(&set2)); // {} { 1 }
+ set2.insert(200);
+ assert!(set1.is_subset(&set2)); // {} { 1, 2 }
+ set1.insert(200);
+ assert!(set1.is_subset(&set2)); // { 2 } { 1, 2 }
+ set1.insert(300);
+ assert!(!set1.is_subset(&set2)); // { 2, 3 } { 1, 2 }
+ set2.insert(300);
+ assert!(set1.is_subset(&set2)); // { 2, 3 } { 1, 2, 3 }
+ set2.insert(400);
+ assert!(set1.is_subset(&set2)); // { 2, 3 } { 1, 2, 3, 4 }
+ set2.remove(&100);
+ assert!(set1.is_subset(&set2)); // { 2, 3 } { 2, 3, 4 }
+ set2.remove(&300);
+ assert!(!set1.is_subset(&set2)); // { 2, 3 } { 2, 4 }
+ set1.remove(&300);
+ assert!(set1.is_subset(&set2)); // { 2 } { 2, 4 }
+ }
+
+ #[test]
+ fn test_bitv_set_is_disjoint() {
+ let a = BitvSet::from_bitv(from_bytes([0b10100010]));
+ let b = BitvSet::from_bitv(from_bytes([0b01000000]));
+ let c = BitvSet::new();
+ let d = BitvSet::from_bitv(from_bytes([0b00110000]));
+
+ assert!(!a.is_disjoint(&d));
+ assert!(!d.is_disjoint(&a));
+
+ assert!(a.is_disjoint(&b))
+ assert!(a.is_disjoint(&c))
+ assert!(b.is_disjoint(&a))
+ assert!(b.is_disjoint(&c))
+ assert!(c.is_disjoint(&a))
+ assert!(c.is_disjoint(&b))
+ }
+
+ #[test]
+ fn test_bitv_set_union_with() {
+ //a should grow to include larger elements
+ let mut a = BitvSet::new();
+ a.insert(0);
+ let mut b = BitvSet::new();
+ b.insert(5);
+ let expected = BitvSet::from_bitv(from_bytes([0b10000100]));
+ a.union_with(&b);
+ assert_eq!(a, expected);
+
+ // Standard
+ let mut a = BitvSet::from_bitv(from_bytes([0b10100010]));
+ let mut b = BitvSet::from_bitv(from_bytes([0b01100010]));
+ let c = a.clone();
+ a.union_with(&b);
+ b.union_with(&c);
+ assert_eq!(a.len(), 4);
+ assert_eq!(b.len(), 4);
+ }
+
+ #[test]
+ fn test_bitv_set_intersect_with() {
+ // Explicitly 0'ed bits
+ let mut a = BitvSet::from_bitv(from_bytes([0b10100010]));
+ let mut b = BitvSet::from_bitv(from_bytes([0b00000000]));
+ let c = a.clone();
+ a.intersect_with(&b);
+ b.intersect_with(&c);
+ assert!(a.is_empty());
+ assert!(b.is_empty());
+
+ // Uninitialized bits should behave like 0's
+ let mut a = BitvSet::from_bitv(from_bytes([0b10100010]));
+ let mut b = BitvSet::new();
+ let c = a.clone();
+ a.intersect_with(&b);
+ b.intersect_with(&c);
+ assert!(a.is_empty());
+ assert!(b.is_empty());
+
+ // Standard
+ let mut a = BitvSet::from_bitv(from_bytes([0b10100010]));
+ let mut b = BitvSet::from_bitv(from_bytes([0b01100010]));
+ let c = a.clone();
+ a.intersect_with(&b);
+ b.intersect_with(&c);
+ assert_eq!(a.len(), 2);
+ assert_eq!(b.len(), 2);
+ }
+
+ #[test]
+ fn test_bitv_set_difference_with() {
+ // Explicitly 0'ed bits
+ let mut a = BitvSet::from_bitv(from_bytes([0b00000000]));
+ let b = BitvSet::from_bitv(from_bytes([0b10100010]));
+ a.difference_with(&b);
+ assert!(a.is_empty());
+
+ // Uninitialized bits should behave like 0's
+ let mut a = BitvSet::new();
+ let b = BitvSet::from_bitv(from_bytes([0b11111111]));
+ a.difference_with(&b);
+ assert!(a.is_empty());
+
+ // Standard
+ let mut a = BitvSet::from_bitv(from_bytes([0b10100010]));
+ let mut b = BitvSet::from_bitv(from_bytes([0b01100010]));
+ let c = a.clone();
+ a.difference_with(&b);
+ b.difference_with(&c);
+ assert_eq!(a.len(), 1);
+ assert_eq!(b.len(), 1);
+ }
+
+ #[test]
+ fn test_bitv_set_symmetric_difference_with() {
+ //a should grow to include larger elements
+ let mut a = BitvSet::new();
+ a.insert(0);
+ a.insert(1);
+ let mut b = BitvSet::new();
+ b.insert(1);
+ b.insert(5);
+ let expected = BitvSet::from_bitv(from_bytes([0b10000100]));
+ a.symmetric_difference_with(&b);
+ assert_eq!(a, expected);
+
+ let mut a = BitvSet::from_bitv(from_bytes([0b10100010]));
+ let b = BitvSet::new();
+ let c = a.clone();
+ a.symmetric_difference_with(&b);
+ assert_eq!(a, c);
+
+ // Standard
+ let mut a = BitvSet::from_bitv(from_bytes([0b11100010]));
+ let mut b = BitvSet::from_bitv(from_bytes([0b01101010]));
+ let c = a.clone();
+ a.symmetric_difference_with(&b);
+ b.symmetric_difference_with(&c);
+ assert_eq!(a.len(), 2);
+ assert_eq!(b.len(), 2);
+ }
+
+ #[test]
+ fn test_bitv_set_eq() {
+ let a = BitvSet::from_bitv(from_bytes([0b10100010]));
+ let b = BitvSet::from_bitv(from_bytes([0b00000000]));
+ let c = BitvSet::new();
+
+ assert!(a == a);
+ assert!(a != b);
+ assert!(a != c);
+ assert!(b == b);
+ assert!(b == c);
+ assert!(c == c);
+ }
+
+ #[test]
+ fn test_bitv_set_cmp() {
+ let a = BitvSet::from_bitv(from_bytes([0b10100010]));
+ let b = BitvSet::from_bitv(from_bytes([0b00000000]));
+ let c = BitvSet::new();
+
+ assert_eq!(a.cmp(&b), Greater);
+ assert_eq!(a.cmp(&c), Greater);
+ assert_eq!(b.cmp(&a), Less);
+ assert_eq!(b.cmp(&c), Equal);
+ assert_eq!(c.cmp(&a), Less);
+ assert_eq!(c.cmp(&b), Equal);
+ }
+
+ #[test]
+ fn test_bitv_remove() {
+ let mut a = BitvSet::new();
+
+ assert!(a.insert(1));
+ assert!(a.remove(&1));
+
+ assert!(a.insert(100));
+ assert!(a.remove(&100));
+
+ assert!(a.insert(1000));
+ assert!(a.remove(&1000));
+ a.shrink_to_fit();
+ assert_eq!(a.capacity(), u32::BITS);
+ }
+
+ #[test]
+ fn test_bitv_lt() {
+ let mut a = Bitv::with_capacity(5u, false);
+ let mut b = Bitv::with_capacity(5u, false);
+
+ assert!(!(a < b) && !(b < a));
+ b.set(2, true);
+ assert!(a < b);
+ a.set(3, true);
+ assert!(a < b);
+ a.set(2, true);
+ assert!(!(a < b) && b < a);
+ b.set(0, true);
+ assert!(a < b);
+ }
+
+ #[test]
+ fn test_ord() {
+ let mut a = Bitv::with_capacity(5u, false);
+ let mut b = Bitv::with_capacity(5u, false);
+
+ assert!(a <= b && a >= b);
+ a.set(1, true);
+ assert!(a > b && a >= b);
+ assert!(b < a && b <= a);
+ b.set(1, true);
+ b.set(2, true);
+ assert!(b > a && b >= a);
+ assert!(a < b && a <= b);
+ }
+
+ #[test]
+ fn test_bitv_clone() {
+ let mut a = BitvSet::new();
+
+ assert!(a.insert(1));
+ assert!(a.insert(100));
+ assert!(a.insert(1000));
+
+ let mut b = a.clone();
+
+ assert!(a == b);
+
+ assert!(b.remove(&1));
+ assert!(a.contains(&1));
+
+ assert!(a.remove(&1000));
+ assert!(b.contains(&1000));
+ }
+
+ #[test]
+ fn test_small_bitv_tests() {
+ let v = from_bytes([0]);
+ assert!(!v.all());
+ assert!(!v.any());
+ assert!(v.none());
+
+ let v = from_bytes([0b00010100]);
+ assert!(!v.all());
+ assert!(v.any());
+ assert!(!v.none());
+
+ let v = from_bytes([0xFF]);
+ assert!(v.all());
+ assert!(v.any());
+ assert!(!v.none());
+ }
+
+ #[test]
+ fn test_big_bitv_tests() {
+ let v = from_bytes([ // 88 bits
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0]);
+ assert!(!v.all());
+ assert!(!v.any());
+ assert!(v.none());
+
+ let v = from_bytes([ // 88 bits
+ 0, 0, 0b00010100, 0,
+ 0, 0, 0, 0b00110100,
+ 0, 0, 0]);
+ assert!(!v.all());
+ assert!(v.any());
+ assert!(!v.none());
+
+ let v = from_bytes([ // 88 bits
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF]);
+ assert!(v.all());
+ assert!(v.any());
+ assert!(!v.none());
+ }
+
+ #[test]
+ fn test_bitv_push_pop() {
+ let mut s = Bitv::with_capacity(5 * u32::BITS - 2, false);
+ assert_eq!(s.len(), 5 * u32::BITS - 2);
+ assert_eq!(s.get(5 * u32::BITS - 3), false);
+ s.push(true);
+ s.push(true);
+ assert_eq!(s.get(5 * u32::BITS - 2), true);
+ assert_eq!(s.get(5 * u32::BITS - 1), true);
+ // Here the internal vector will need to be extended
+ s.push(false);
+ assert_eq!(s.get(5 * u32::BITS), false);
+ s.push(false);
+ assert_eq!(s.get(5 * u32::BITS + 1), false);
+ assert_eq!(s.len(), 5 * u32::BITS + 2);
+ // Pop it all off
+ assert_eq!(s.pop(), false);
+ assert_eq!(s.pop(), false);
+ assert_eq!(s.pop(), true);
+ assert_eq!(s.pop(), true);
+ assert_eq!(s.len(), 5 * u32::BITS - 2);
+ }
+
+ #[test]
+ fn test_bitv_truncate() {
+ let mut s = Bitv::with_capacity(5 * u32::BITS, true);
+
+ assert_eq!(s, Bitv::with_capacity(5 * u32::BITS, true));
+ assert_eq!(s.len(), 5 * u32::BITS);
+ s.truncate(4 * u32::BITS);
+ assert_eq!(s, Bitv::with_capacity(4 * u32::BITS, true));
+ assert_eq!(s.len(), 4 * u32::BITS);
+ // Truncating to a size > s.len() should be a noop
+ s.truncate(5 * u32::BITS);
+ assert_eq!(s, Bitv::with_capacity(4 * u32::BITS, true));
+ assert_eq!(s.len(), 4 * u32::BITS);
+ s.truncate(3 * u32::BITS - 10);
+ assert_eq!(s, Bitv::with_capacity(3 * u32::BITS - 10, true));
+ assert_eq!(s.len(), 3 * u32::BITS - 10);
+ s.truncate(0);
+ assert_eq!(s, Bitv::with_capacity(0, true));
+ assert_eq!(s.len(), 0);
+ }
+
+ #[test]
+ fn test_bitv_reserve() {
+ let mut s = Bitv::with_capacity(5 * u32::BITS, true);
+ // Check capacity
+ assert_eq!(s.capacity(), 5 * u32::BITS);
+ s.reserve(2 * u32::BITS);
+ assert_eq!(s.capacity(), 5 * u32::BITS);
+ s.reserve(7 * u32::BITS);
+ assert_eq!(s.capacity(), 7 * u32::BITS);
+ s.reserve(7 * u32::BITS);
+ assert_eq!(s.capacity(), 7 * u32::BITS);
+ s.reserve(7 * u32::BITS + 1);
+ assert_eq!(s.capacity(), 8 * u32::BITS);
+ // Check that length hasn't changed
+ assert_eq!(s.len(), 5 * u32::BITS);
+ s.push(true);
+ s.push(false);
+ s.push(true);
+ assert_eq!(s.get(5 * u32::BITS - 1), true);
+ assert_eq!(s.get(5 * u32::BITS - 0), true);
+ assert_eq!(s.get(5 * u32::BITS + 1), false);
+ assert_eq!(s.get(5 * u32::BITS + 2), true);
+ }
+
+ #[test]
+ fn test_bitv_grow() {
+ let mut bitv = from_bytes([0b10110110, 0b00000000, 0b10101010]);
+ bitv.grow(32, true);
+ assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b10101010,
+ 0xFF, 0xFF, 0xFF, 0xFF]));
+ bitv.grow(64, false);
+ assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b10101010,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0]));
+ bitv.grow(16, true);
+ assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b10101010,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]));
+ }
+
+ #[test]
+ fn test_bitv_extend() {
+ let mut bitv = from_bytes([0b10110110, 0b00000000, 0b11111111]);
+ let ext = from_bytes([0b01001001, 0b10010010, 0b10111101]);
+ bitv.extend(ext.iter());
+ assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b11111111,
+ 0b01001001, 0b10010010, 0b10111101]));
+ }
+
+ #[test]
+ fn test_bitv_set_show() {
+ let mut s = BitvSet::new();
+ s.insert(1);
+ s.insert(10);
+ s.insert(50);
+ s.insert(2);
+ assert_eq!("{1, 2, 10, 50}".to_string(), s.to_string());
+ }
+
+ fn rng() -> rand::IsaacRng {
+ let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
+ rand::SeedableRng::from_seed(seed)
+ }
+
+ #[bench]
+ fn bench_uint_small(b: &mut Bencher) {
+ let mut r = rng();
+ let mut bitv = 0 as uint;
+ b.iter(|| {
+ for _ in range(0u, 100) {
+ bitv |= 1 << ((r.next_u32() as uint) % u32::BITS);
+ }
+ &bitv
+ })
+ }
+
+ #[bench]
+ fn bench_bitv_set_big_fixed(b: &mut Bencher) {
+ let mut r = rng();
+ let mut bitv = Bitv::with_capacity(BENCH_BITS, false);
+ b.iter(|| {
+ for _ in range(0u, 100) {
+ bitv.set((r.next_u32() as uint) % BENCH_BITS, true);
+ }
+ &bitv
+ })
+ }
+
+ #[bench]
+ fn bench_bitv_set_big_variable(b: &mut Bencher) {
+ let mut r = rng();
+ let mut bitv = Bitv::with_capacity(BENCH_BITS, false);
+ b.iter(|| {
+ for _ in range(0u, 100) {
+ bitv.set((r.next_u32() as uint) % BENCH_BITS, r.gen());
+ }
+ &bitv
+ })
+ }
+
+ #[bench]
+ fn bench_bitv_set_small(b: &mut Bencher) {
+ let mut r = rng();
+ let mut bitv = Bitv::with_capacity(u32::BITS, false);
+ b.iter(|| {
+ for _ in range(0u, 100) {
+ bitv.set((r.next_u32() as uint) % u32::BITS, true);
+ }
+ &bitv
+ })
+ }
+
+ #[bench]
+ fn bench_bitvset_small(b: &mut Bencher) {
+ let mut r = rng();
+ let mut bitv = BitvSet::new();
+ b.iter(|| {
+ for _ in range(0u, 100) {
+ bitv.insert((r.next_u32() as uint) % u32::BITS);
+ }
+ &bitv
+ })
+ }
+
+ #[bench]
+ fn bench_bitvset_big(b: &mut Bencher) {
+ let mut r = rng();
+ let mut bitv = BitvSet::new();
+ b.iter(|| {
+ for _ in range(0u, 100) {
+ bitv.insert((r.next_u32() as uint) % BENCH_BITS);
+ }
+ &bitv
+ })
+ }
+
+ #[bench]
+ fn bench_bitv_big_union(b: &mut Bencher) {
+ let mut b1 = Bitv::with_capacity(BENCH_BITS, false);
+ let b2 = Bitv::with_capacity(BENCH_BITS, false);
+ b.iter(|| {
+ b1.union(&b2)
+ })
+ }
+
+ #[bench]
+ fn bench_bitv_small_iter(b: &mut Bencher) {
+ let bitv = Bitv::with_capacity(u32::BITS, false);
+ b.iter(|| {
+ let mut sum = 0u;
+ for _ in range(0u, 10) {
+ for pres in bitv.iter() {
+ sum += pres as uint;
+ }
+ }
+ sum
+ })
+ }
+
+ #[bench]
+ fn bench_bitv_big_iter(b: &mut Bencher) {
+ let bitv = Bitv::with_capacity(BENCH_BITS, false);
+ b.iter(|| {
+ let mut sum = 0u;
+ for pres in bitv.iter() {
+ sum += pres as uint;
+ }
+ sum
+ })
+ }
+
+ #[bench]
+ fn bench_bitvset_iter(b: &mut Bencher) {
+ let bitv = BitvSet::from_bitv(from_fn(BENCH_BITS,
+ |idx| {idx % 3 == 0}));
+ b.iter(|| {
+ let mut sum = 0u;
+ for idx in bitv.iter() {
+ sum += idx as uint;
+ }
+ sum
+ })
+ }
+}
+++ /dev/null
-// Copyright 2012-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.
-
-//! Collections implemented with bit vectors.
-//!
-//! # Example
-//!
-//! This is a simple example of the [Sieve of Eratosthenes][sieve]
-//! which calculates prime numbers up to a given limit.
-//!
-//! [sieve]: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
-//!
-//! ```
-//! use std::collections::{BitvSet, Bitv};
-//! use std::iter;
-//!
-//! let max_prime = 10000;
-//!
-//! // Store the primes as a BitvSet
-//! let primes = {
-//! // Assume all numbers are prime to begin, and then we
-//! // cross off non-primes progressively
-//! let mut bv = Bitv::with_capacity(max_prime, true);
-//!
-//! // Neither 0 nor 1 are prime
-//! bv.set(0, false);
-//! bv.set(1, false);
-//!
-//! for i in iter::range_inclusive(2, (max_prime as f64).sqrt() as uint) {
-//! // if i is a prime
-//! if bv[i] {
-//! // Mark all multiples of i as non-prime (any multiples below i * i
-//! // will have been marked as non-prime previously)
-//! for j in iter::range_step(i * i, max_prime, i) { bv.set(j, false) }
-//! }
-//! }
-//! BitvSet::from_bitv(bv)
-//! };
-//!
-//! // Simple primality tests below our max bound
-//! let print_primes = 20;
-//! print!("The primes below {} are: ", print_primes);
-//! for x in range(0, print_primes) {
-//! if primes.contains(&x) {
-//! print!("{} ", x);
-//! }
-//! }
-//! println!("");
-//!
-//! // We can manipulate the internal Bitv
-//! let num_primes = primes.get_ref().iter().filter(|x| *x).count();
-//! println!("There are {} primes below {}", num_primes, max_prime);
-//! ```
-
-use core::prelude::*;
-
-use core::cmp;
-use core::default::Default;
-use core::fmt;
-use core::iter::{Chain, Enumerate, Repeat, Skip, Take};
-use core::iter;
-use core::slice;
-use core::u32;
-use std::hash;
-
-use vec::Vec;
-
-type MatchWords<'a> = Chain<MaskWords<'a>, Skip<Take<Enumerate<Repeat<u32>>>>>;
-// Take two BitV's, and return iterators of their words, where the shorter one
-// has been padded with 0's
-fn match_words <'a,'b>(a: &'a Bitv, b: &'b Bitv) -> (MatchWords<'a>, MatchWords<'b>) {
- let a_len = a.storage.len();
- let b_len = b.storage.len();
-
- // have to uselessly pretend to pad the longer one for type matching
- if a_len < b_len {
- (a.mask_words(0).chain(Repeat::new(0u32).enumerate().take(b_len).skip(a_len)),
- b.mask_words(0).chain(Repeat::new(0u32).enumerate().take(0).skip(0)))
- } else {
- (a.mask_words(0).chain(Repeat::new(0u32).enumerate().take(0).skip(0)),
- b.mask_words(0).chain(Repeat::new(0u32).enumerate().take(a_len).skip(b_len)))
- }
-}
-
-static TRUE: bool = true;
-static FALSE: bool = false;
-
-/// The bitvector type.
-///
-/// # Example
-///
-/// ```rust
-/// use collections::Bitv;
-///
-/// let mut bv = Bitv::with_capacity(10, false);
-///
-/// // insert all primes less than 10
-/// bv.set(2, true);
-/// bv.set(3, true);
-/// bv.set(5, true);
-/// bv.set(7, true);
-/// println!("{}", bv.to_string());
-/// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
-///
-/// // flip all values in bitvector, producing non-primes less than 10
-/// bv.negate();
-/// println!("{}", bv.to_string());
-/// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
-///
-/// // reset bitvector to empty
-/// bv.clear();
-/// println!("{}", bv.to_string());
-/// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
-/// ```
-pub struct Bitv {
- /// Internal representation of the bit vector
- storage: Vec<u32>,
- /// The number of valid bits in the internal representation
- nbits: uint
-}
-
-impl Index<uint,bool> for Bitv {
- #[inline]
- fn index<'a>(&'a self, i: &uint) -> &'a bool {
- if self.get(*i) {
- &TRUE
- } else {
- &FALSE
- }
- }
-}
-
-struct MaskWords<'a> {
- iter: slice::Items<'a, u32>,
- next_word: Option<&'a u32>,
- last_word_mask: u32,
- offset: uint
-}
-
-impl<'a> Iterator<(uint, u32)> for MaskWords<'a> {
- /// Returns (offset, word)
- #[inline]
- fn next<'a>(&'a mut self) -> Option<(uint, u32)> {
- let ret = self.next_word;
- match ret {
- Some(&w) => {
- self.next_word = self.iter.next();
- self.offset += 1;
- // The last word may need to be masked
- if self.next_word.is_none() {
- Some((self.offset - 1, w & self.last_word_mask))
- } else {
- Some((self.offset - 1, w))
- }
- },
- None => None
- }
- }
-}
-
-impl Bitv {
- #[inline]
- fn process(&mut self, other: &Bitv, op: |u32, u32| -> u32) -> bool {
- let len = other.storage.len();
- assert_eq!(self.storage.len(), len);
- let mut changed = false;
- // Notice: `a` is *not* masked here, which is fine as long as
- // `op` is a bitwise operation, since any bits that should've
- // been masked were fine to change anyway. `b` is masked to
- // make sure its unmasked bits do not cause damage.
- for (a, (_, b)) in self.storage.iter_mut()
- .zip(other.mask_words(0)) {
- let w = op(*a, b);
- if *a != w {
- changed = true;
- *a = w;
- }
- }
- changed
- }
-
- #[inline]
- fn mask_words<'a>(&'a self, mut start: uint) -> MaskWords<'a> {
- if start > self.storage.len() {
- start = self.storage.len();
- }
- let mut iter = self.storage[start..].iter();
- MaskWords {
- next_word: iter.next(),
- iter: iter,
- last_word_mask: {
- let rem = self.nbits % u32::BITS;
- if rem > 0 {
- (1 << rem) - 1
- } else { !0 }
- },
- offset: start
- }
- }
-
- /// Creates an empty `Bitv`.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::Bitv;
- /// let mut bv = Bitv::new();
- /// ```
- pub fn new() -> Bitv {
- Bitv { storage: Vec::new(), nbits: 0 }
- }
-
- /// Creates a `Bitv` that holds `nbits` elements, setting each element
- /// to `init`.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::Bitv;
- ///
- /// let mut bv = Bitv::with_capacity(10u, false);
- /// assert_eq!(bv.len(), 10u);
- /// for x in bv.iter() {
- /// assert_eq!(x, false);
- /// }
- /// ```
- pub fn with_capacity(nbits: uint, init: bool) -> Bitv {
- let mut bitv = Bitv {
- storage: Vec::from_elem((nbits + u32::BITS - 1) / u32::BITS,
- if init { !0u32 } else { 0u32 }),
- nbits: nbits
- };
-
- // Zero out any unused bits in the highest word if necessary
- let used_bits = bitv.nbits % u32::BITS;
- if init && used_bits != 0 {
- let largest_used_word = (bitv.nbits + u32::BITS - 1) / u32::BITS - 1;
- bitv.storage[largest_used_word] &= (1 << used_bits) - 1;
- }
-
- bitv
- }
-
- /// Retrieves the value at index `i`.
- ///
- /// # Failure
- ///
- /// Fails if `i` is out of bounds.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::bitv;
- ///
- /// let bv = bitv::from_bytes([0b01100000]);
- /// assert_eq!(bv.get(0), false);
- /// assert_eq!(bv.get(1), true);
- ///
- /// // Can also use array indexing
- /// assert_eq!(bv[1], true);
- /// ```
- #[inline]
- pub fn get(&self, i: uint) -> bool {
- assert!(i < self.nbits);
- let w = i / u32::BITS;
- let b = i % u32::BITS;
- let x = self.storage[w] & (1 << b);
- x != 0
- }
-
- /// Sets the value of a bit at a index `i`.
- ///
- /// # Failure
- ///
- /// Fails if `i` is out of bounds.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::Bitv;
- ///
- /// let mut bv = Bitv::with_capacity(5, false);
- /// bv.set(3, true);
- /// assert_eq!(bv[3], true);
- /// ```
- #[inline]
- pub fn set(&mut self, i: uint, x: bool) {
- assert!(i < self.nbits);
- let w = i / u32::BITS;
- let b = i % u32::BITS;
- let flag = 1 << b;
- let val = if x { self.storage[w] | flag }
- else { self.storage[w] & !flag };
- self.storage[w] = val;
- }
-
- /// Sets all bits to 1.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::bitv;
- ///
- /// let before = 0b01100000;
- /// let after = 0b11111111;
- ///
- /// let mut bv = bitv::from_bytes([before]);
- /// bv.set_all();
- /// assert_eq!(bv, bitv::from_bytes([after]));
- /// ```
- #[inline]
- pub fn set_all(&mut self) {
- for w in self.storage.iter_mut() { *w = !0u32; }
- }
-
- /// Flips all bits.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::bitv;
- ///
- /// let before = 0b01100000;
- /// let after = 0b10011111;
- ///
- /// let mut bv = bitv::from_bytes([before]);
- /// bv.negate();
- /// assert_eq!(bv, bitv::from_bytes([after]));
- /// ```
- #[inline]
- pub fn negate(&mut self) {
- for w in self.storage.iter_mut() { *w = !*w; }
- }
-
- /// Calculates the union of two bitvectors. This acts like the bitwise `or`
- /// function.
- ///
- /// Sets `self` to the union of `self` and `other`. Both bitvectors must be
- /// the same length. Returns `true` if `self` changed.
- ///
- /// # Failure
- ///
- /// Fails if the bitvectors are of different lengths.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::bitv;
- ///
- /// let a = 0b01100100;
- /// let b = 0b01011010;
- /// let res = 0b01111110;
- ///
- /// let mut a = bitv::from_bytes([a]);
- /// let b = bitv::from_bytes([b]);
- ///
- /// assert!(a.union(&b));
- /// assert_eq!(a, bitv::from_bytes([res]));
- /// ```
- #[inline]
- pub fn union(&mut self, other: &Bitv) -> bool {
- self.process(other, |w1, w2| w1 | w2)
- }
-
- /// Calculates the intersection of two bitvectors. This acts like the
- /// bitwise `and` function.
- ///
- /// Sets `self` to the intersection of `self` and `other`. Both bitvectors
- /// must be the same length. Returns `true` if `self` changed.
- ///
- /// # Failure
- ///
- /// Fails if the bitvectors are of different lengths.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::bitv;
- ///
- /// let a = 0b01100100;
- /// let b = 0b01011010;
- /// let res = 0b01000000;
- ///
- /// let mut a = bitv::from_bytes([a]);
- /// let b = bitv::from_bytes([b]);
- ///
- /// assert!(a.intersect(&b));
- /// assert_eq!(a, bitv::from_bytes([res]));
- /// ```
- #[inline]
- pub fn intersect(&mut self, other: &Bitv) -> bool {
- self.process(other, |w1, w2| w1 & w2)
- }
-
- /// Calculates the difference between two bitvectors.
- ///
- /// Sets each element of `self` to the value of that element minus the
- /// element of `other` at the same index. Both bitvectors must be the same
- /// length. Returns `true` if `self` changed.
- ///
- /// # Failure
- ///
- /// Fails if the bitvectors are of different length.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::bitv;
- ///
- /// let a = 0b01100100;
- /// let b = 0b01011010;
- /// let a_b = 0b00100100; // a - b
- /// let b_a = 0b00011010; // b - a
- ///
- /// let mut bva = bitv::from_bytes([a]);
- /// let bvb = bitv::from_bytes([b]);
- ///
- /// assert!(bva.difference(&bvb));
- /// assert_eq!(bva, bitv::from_bytes([a_b]));
- ///
- /// let bva = bitv::from_bytes([a]);
- /// let mut bvb = bitv::from_bytes([b]);
- ///
- /// assert!(bvb.difference(&bva));
- /// assert_eq!(bvb, bitv::from_bytes([b_a]));
- /// ```
- #[inline]
- pub fn difference(&mut self, other: &Bitv) -> bool {
- self.process(other, |w1, w2| w1 & !w2)
- }
-
- /// Returns `true` if all bits are 1.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::Bitv;
- ///
- /// let mut bv = Bitv::with_capacity(5, true);
- /// assert_eq!(bv.all(), true);
- ///
- /// bv.set(1, false);
- /// assert_eq!(bv.all(), false);
- /// ```
- #[inline]
- pub fn all(&self) -> bool {
- let mut last_word = !0u32;
- // Check that every word but the last is all-ones...
- self.mask_words(0).all(|(_, elem)|
- { let tmp = last_word; last_word = elem; tmp == !0u32 }) &&
- // ...and that the last word is ones as far as it needs to be
- (last_word == ((1 << self.nbits % u32::BITS) - 1) || last_word == !0u32)
- }
-
- /// Returns an iterator over the elements of the vector in order.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::bitv;
- ///
- /// let bv = bitv::from_bytes([0b01110100, 0b10010010]);
- /// assert_eq!(bv.iter().filter(|x| *x).count(), 7);
- /// ```
- #[inline]
- pub fn iter<'a>(&'a self) -> Bits<'a> {
- Bits {bitv: self, next_idx: 0, end_idx: self.nbits}
- }
-
- /// Returns `true` if all bits are 0.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::Bitv;
- ///
- /// let mut bv = Bitv::with_capacity(10, false);
- /// assert_eq!(bv.none(), true);
- ///
- /// bv.set(3, true);
- /// assert_eq!(bv.none(), false);
- /// ```
- pub fn none(&self) -> bool {
- self.mask_words(0).all(|(_, w)| w == 0)
- }
-
- /// Returns `true` if any bit is 1.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::Bitv;
- ///
- /// let mut bv = Bitv::with_capacity(10, false);
- /// assert_eq!(bv.any(), false);
- ///
- /// bv.set(3, true);
- /// assert_eq!(bv.any(), true);
- /// ```
- #[inline]
- pub fn any(&self) -> bool {
- !self.none()
- }
-
- /// Organises the bits into bytes, such that the first bit in the
- /// `Bitv` becomes the high-order bit of the first byte. If the
- /// size of the `Bitv` is not a multiple of eight then trailing bits
- /// will be filled-in with `false`.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::Bitv;
- ///
- /// let mut bv = Bitv::with_capacity(3, true);
- /// bv.set(1, false);
- ///
- /// assert_eq!(bv.to_bytes(), vec!(0b10100000));
- ///
- /// let mut bv = Bitv::with_capacity(9, false);
- /// bv.set(2, true);
- /// bv.set(8, true);
- ///
- /// assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000));
- /// ```
- pub fn to_bytes(&self) -> Vec<u8> {
- fn bit (bitv: &Bitv, byte: uint, bit: uint) -> u8 {
- let offset = byte * 8 + bit;
- if offset >= bitv.nbits {
- 0
- } else {
- bitv.get(offset) as u8 << (7 - bit)
- }
- }
-
- let len = self.nbits/8 +
- if self.nbits % 8 == 0 { 0 } else { 1 };
- Vec::from_fn(len, |i|
- bit(self, i, 0) |
- bit(self, i, 1) |
- bit(self, i, 2) |
- bit(self, i, 3) |
- bit(self, i, 4) |
- bit(self, i, 5) |
- bit(self, i, 6) |
- bit(self, i, 7)
- )
- }
-
- /// Transforms `self` into a `Vec<bool>` by turning each bit into a `bool`.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::bitv;
- ///
- /// let bv = bitv::from_bytes([0b10100000]);
- /// assert_eq!(bv.to_bools(), vec!(true, false, true, false,
- /// false, false, false, false));
- /// ```
- pub fn to_bools(&self) -> Vec<bool> {
- Vec::from_fn(self.nbits, |i| self.get(i))
- }
-
- /// Compares a `Bitv` to a slice of `bool`s.
- /// Both the `Bitv` and slice must have the same length.
- ///
- /// # Failure
- ///
- /// Fails if the the `Bitv` and slice are of different length.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::bitv;
- ///
- /// let bv = bitv::from_bytes([0b10100000]);
- ///
- /// assert!(bv.eq_vec([true, false, true, false,
- /// false, false, false, false]));
- /// ```
- pub fn eq_vec(&self, v: &[bool]) -> bool {
- assert_eq!(self.nbits, v.len());
- let mut i = 0;
- while i < self.nbits {
- if self.get(i) != v[i] { return false; }
- i = i + 1;
- }
- true
- }
-
- /// Shortens a `Bitv`, dropping excess elements.
- ///
- /// If `len` is greater than the vector's current length, this has no
- /// effect.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::bitv;
- ///
- /// let mut bv = bitv::from_bytes([0b01001011]);
- /// bv.truncate(2);
- /// assert!(bv.eq_vec([false, true]));
- /// ```
- pub fn truncate(&mut self, len: uint) {
- if len < self.len() {
- self.nbits = len;
- let word_len = (len + u32::BITS - 1) / u32::BITS;
- self.storage.truncate(word_len);
- if len % u32::BITS > 0 {
- let mask = (1 << len % u32::BITS) - 1;
- self.storage[word_len - 1] &= mask;
- }
- }
- }
-
- /// Grows the vector to be able to store `size` bits without resizing.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::Bitv;
- ///
- /// let mut bv = Bitv::with_capacity(3, false);
- /// bv.reserve(10);
- /// assert_eq!(bv.len(), 3);
- /// assert!(bv.capacity() >= 10);
- /// ```
- pub fn reserve(&mut self, size: uint) {
- let old_size = self.storage.len();
- let new_size = (size + u32::BITS - 1) / u32::BITS;
- if old_size < new_size {
- self.storage.grow(new_size - old_size, 0);
- }
- }
-
- /// Returns the capacity in bits for this bit vector. Inserting any
- /// element less than this amount will not trigger a resizing.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::Bitv;
- ///
- /// let mut bv = Bitv::new();
- /// bv.reserve(10);
- /// assert!(bv.capacity() >= 10);
- /// ```
- #[inline]
- pub fn capacity(&self) -> uint {
- self.storage.len() * u32::BITS
- }
-
- /// Grows the `Bitv` in-place, adding `n` copies of `value` to the `Bitv`.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::bitv;
- ///
- /// let mut bv = bitv::from_bytes([0b01001011]);
- /// bv.grow(2, true);
- /// assert_eq!(bv.len(), 10);
- /// assert_eq!(bv.to_bytes(), vec!(0b01001011, 0b11000000));
- /// ```
- pub fn grow(&mut self, n: uint, value: bool) {
- let new_nbits = self.nbits + n;
- let new_nwords = (new_nbits + u32::BITS - 1) / u32::BITS;
- let full_value = if value { !0 } else { 0 };
- // Correct the old tail word
- let old_last_word = (self.nbits + u32::BITS - 1) / u32::BITS - 1;
- if self.nbits % u32::BITS > 0 {
- let overhang = self.nbits % u32::BITS; // # of already-used bits
- let mask = !((1 << overhang) - 1); // e.g. 5 unused bits => 111110....0
- if value {
- self.storage[old_last_word] |= mask;
- } else {
- self.storage[old_last_word] &= !mask;
- }
- }
- // Fill in words after the old tail word
- let stop_idx = cmp::min(self.storage.len(), new_nwords);
- for idx in range(old_last_word + 1, stop_idx) {
- self.storage[idx] = full_value;
- }
- // Allocate new words, if needed
- if new_nwords > self.storage.len() {
- let to_add = new_nwords - self.storage.len();
- self.storage.grow(to_add, full_value);
-
- // Zero out and unused bits in the new tail word
- if value {
- let tail_word = new_nwords - 1;
- let used_bits = new_nbits % u32::BITS;
- self.storage[tail_word] &= (1 << used_bits) - 1;
- }
- }
- // Adjust internal bit count
- self.nbits = new_nbits;
- }
-
- /// Shortens by one element and returns the removed element.
- ///
- /// # Failure
- ///
- /// Assert if empty.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::bitv;
- ///
- /// let mut bv = bitv::from_bytes([0b01001001]);
- /// assert_eq!(bv.pop(), true);
- /// assert_eq!(bv.pop(), false);
- /// assert_eq!(bv.len(), 6);
- /// assert_eq!(bv.to_bytes(), vec!(0b01001000));
- /// ```
- pub fn pop(&mut self) -> bool {
- let ret = self.get(self.nbits - 1);
- // If we are unusing a whole word, make sure it is zeroed out
- if self.nbits % u32::BITS == 1 {
- self.storage[self.nbits / u32::BITS] = 0;
- }
- self.nbits -= 1;
- ret
- }
-
- /// Pushes a `bool` onto the end.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::Bitv;
- ///
- /// let mut bv = Bitv::new();
- /// bv.push(true);
- /// bv.push(false);
- /// assert!(bv.eq_vec([true, false]));
- /// ```
- pub fn push(&mut self, elem: bool) {
- let insert_pos = self.nbits;
- self.nbits += 1;
- if self.storage.len() * u32::BITS < self.nbits {
- self.storage.push(0);
- }
- self.set(insert_pos, elem);
- }
-
- /// Return the total number of bits in this vector
- #[inline]
- pub fn len(&self) -> uint { self.nbits }
-
- /// Returns true if there are no bits in this vector
- #[inline]
- pub fn is_empty(&self) -> bool { self.len() == 0 }
-
- /// Clears all bits in this vector.
- #[inline]
- pub fn clear(&mut self) {
- for w in self.storage.iter_mut() { *w = 0u32; }
- }
-}
-
-/// Transforms a byte-vector into a `Bitv`. Each byte becomes eight bits,
-/// with the most significant bits of each byte coming first. Each
-/// bit becomes `true` if equal to 1 or `false` if equal to 0.
-///
-/// # Example
-///
-/// ```
-/// use std::collections::bitv;
-///
-/// let bv = bitv::from_bytes([0b10100000, 0b00010010]);
-/// assert!(bv.eq_vec([true, false, true, false,
-/// false, false, false, false,
-/// false, false, false, true,
-/// false, false, true, false]));
-/// ```
-pub fn from_bytes(bytes: &[u8]) -> Bitv {
- from_fn(bytes.len() * 8, |i| {
- let b = bytes[i / 8] as u32;
- let offset = i % 8;
- b >> (7 - offset) & 1 == 1
- })
-}
-
-/// Creates a `Bitv` of the specified length where the value at each
-/// index is `f(index)`.
-///
-/// # Example
-///
-/// ```
-/// use std::collections::bitv::from_fn;
-///
-/// let bv = from_fn(5, |i| { i % 2 == 0 });
-/// assert!(bv.eq_vec([true, false, true, false, true]));
-/// ```
-pub fn from_fn(len: uint, f: |index: uint| -> bool) -> Bitv {
- let mut bitv = Bitv::with_capacity(len, false);
- for i in range(0u, len) {
- bitv.set(i, f(i));
- }
- bitv
-}
-
-impl Default for Bitv {
- #[inline]
- fn default() -> Bitv { Bitv::new() }
-}
-
-impl FromIterator<bool> for Bitv {
- fn from_iter<I:Iterator<bool>>(iterator: I) -> Bitv {
- let mut ret = Bitv::new();
- ret.extend(iterator);
- ret
- }
-}
-
-impl Extendable<bool> for Bitv {
- #[inline]
- fn extend<I: Iterator<bool>>(&mut self, mut iterator: I) {
- let (min, _) = iterator.size_hint();
- let nbits = self.nbits;
- self.reserve(nbits + min);
- for element in iterator {
- self.push(element)
- }
- }
-}
-
-impl Clone for Bitv {
- #[inline]
- fn clone(&self) -> Bitv {
- Bitv { storage: self.storage.clone(), nbits: self.nbits }
- }
-
- #[inline]
- fn clone_from(&mut self, source: &Bitv) {
- self.nbits = source.nbits;
- self.storage.reserve(source.storage.len());
- for (i, w) in self.storage.iter_mut().enumerate() { *w = source.storage[i]; }
- }
-}
-
-impl PartialOrd for Bitv {
- #[inline]
- fn partial_cmp(&self, other: &Bitv) -> Option<Ordering> {
- iter::order::partial_cmp(self.iter(), other.iter())
- }
-}
-
-impl Ord for Bitv {
- #[inline]
- fn cmp(&self, other: &Bitv) -> Ordering {
- iter::order::cmp(self.iter(), other.iter())
- }
-}
-
-impl fmt::Show for Bitv {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- for bit in self.iter() {
- try!(write!(fmt, "{}", if bit { 1u } else { 0u }));
- }
- Ok(())
- }
-}
-
-impl<S: hash::Writer> hash::Hash<S> for Bitv {
- fn hash(&self, state: &mut S) {
- self.nbits.hash(state);
- for (_, elem) in self.mask_words(0) {
- elem.hash(state);
- }
- }
-}
-
-impl cmp::PartialEq for Bitv {
- #[inline]
- fn eq(&self, other: &Bitv) -> bool {
- if self.nbits != other.nbits {
- return false;
- }
- self.mask_words(0).zip(other.mask_words(0)).all(|((_, w1), (_, w2))| w1 == w2)
- }
-}
-
-impl cmp::Eq for Bitv {}
-
-/// An iterator for `Bitv`.
-pub struct Bits<'a> {
- bitv: &'a Bitv,
- next_idx: uint,
- end_idx: uint,
-}
-
-impl<'a> Iterator<bool> for Bits<'a> {
- #[inline]
- fn next(&mut self) -> Option<bool> {
- if self.next_idx != self.end_idx {
- let idx = self.next_idx;
- self.next_idx += 1;
- Some(self.bitv.get(idx))
- } else {
- None
- }
- }
-
- fn size_hint(&self) -> (uint, Option<uint>) {
- let rem = self.end_idx - self.next_idx;
- (rem, Some(rem))
- }
-}
-
-impl<'a> DoubleEndedIterator<bool> for Bits<'a> {
- #[inline]
- fn next_back(&mut self) -> Option<bool> {
- if self.next_idx != self.end_idx {
- self.end_idx -= 1;
- Some(self.bitv.get(self.end_idx))
- } else {
- None
- }
- }
-}
-
-impl<'a> ExactSize<bool> for Bits<'a> {}
-
-impl<'a> RandomAccessIterator<bool> for Bits<'a> {
- #[inline]
- fn indexable(&self) -> uint {
- self.end_idx - self.next_idx
- }
-
- #[inline]
- fn idx(&mut self, index: uint) -> Option<bool> {
- if index >= self.indexable() {
- None
- } else {
- Some(self.bitv.get(index))
- }
- }
-}
-
-/// An implementation of a set using a bit vector as an underlying
-/// representation for holding unsigned numerical elements.
-///
-/// It should also be noted that the amount of storage necessary for holding a
-/// set of objects is proportional to the maximum of the objects when viewed
-/// as a `uint`.
-///
-/// # Example
-///
-/// ```
-/// use std::collections::{BitvSet, Bitv};
-/// use std::collections::bitv;
-///
-/// // It's a regular set
-/// let mut s = BitvSet::new();
-/// s.insert(0);
-/// s.insert(3);
-/// s.insert(7);
-///
-/// s.remove(&7);
-///
-/// if !s.contains(&7) {
-/// println!("There is no 7");
-/// }
-///
-/// // Can initialize from a `Bitv`
-/// let other = BitvSet::from_bitv(bitv::from_bytes([0b11010000]));
-///
-/// s.union_with(&other);
-///
-/// // Print 0, 1, 3 in some order
-/// for x in s.iter() {
-/// println!("{}", x);
-/// }
-///
-/// // Can convert back to a `Bitv`
-/// let bv: Bitv = s.into_bitv();
-/// assert!(bv.get(3));
-/// ```
-#[deriving(Clone)]
-pub struct BitvSet(Bitv);
-
-impl Default for BitvSet {
- #[inline]
- fn default() -> BitvSet { BitvSet::new() }
-}
-
-impl FromIterator<bool> for BitvSet {
- fn from_iter<I:Iterator<bool>>(iterator: I) -> BitvSet {
- let mut ret = BitvSet::new();
- ret.extend(iterator);
- ret
- }
-}
-
-impl Extendable<bool> for BitvSet {
- #[inline]
- fn extend<I: Iterator<bool>>(&mut self, iterator: I) {
- let &BitvSet(ref mut self_bitv) = self;
- self_bitv.extend(iterator);
- }
-}
-
-impl PartialOrd for BitvSet {
- #[inline]
- fn partial_cmp(&self, other: &BitvSet) -> Option<Ordering> {
- let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref());
- iter::order::partial_cmp(a_iter, b_iter)
- }
-}
-
-impl Ord for BitvSet {
- #[inline]
- fn cmp(&self, other: &BitvSet) -> Ordering {
- let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref());
- iter::order::cmp(a_iter, b_iter)
- }
-}
-
-impl cmp::PartialEq for BitvSet {
- #[inline]
- fn eq(&self, other: &BitvSet) -> bool {
- let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref());
- iter::order::eq(a_iter, b_iter)
- }
-}
-
-impl cmp::Eq for BitvSet {}
-
-impl BitvSet {
- /// Creates a new bit vector set with initially no contents.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::BitvSet;
- /// let mut s = BitvSet::new();
- /// ```
- #[inline]
- pub fn new() -> BitvSet {
- BitvSet(Bitv::new())
- }
-
- /// Creates a new bit vector set with initially no contents, able to
- /// hold `nbits` elements without resizing.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::BitvSet;
- /// let mut s = BitvSet::with_capacity(100);
- /// assert!(s.capacity() >= 100);
- /// ```
- #[inline]
- pub fn with_capacity(nbits: uint) -> BitvSet {
- let bitv = Bitv::with_capacity(nbits, false);
- BitvSet::from_bitv(bitv)
- }
-
- /// Creates a new bit vector set from the given bit vector.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::{bitv, BitvSet};
- ///
- /// let bv = bitv::from_bytes([0b01100000]);
- /// let s = BitvSet::from_bitv(bv);
- ///
- /// // Print 1, 2 in arbitrary order
- /// for x in s.iter() {
- /// println!("{}", x);
- /// }
- /// ```
- #[inline]
- pub fn from_bitv(mut bitv: Bitv) -> BitvSet {
- // Mark every bit as valid
- bitv.nbits = bitv.capacity();
- BitvSet(bitv)
- }
-
- /// Returns the capacity in bits for this bit vector. Inserting any
- /// element less than this amount will not trigger a resizing.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::BitvSet;
- ///
- /// let mut s = BitvSet::with_capacity(100);
- /// assert!(s.capacity() >= 100);
- /// ```
- #[inline]
- pub fn capacity(&self) -> uint {
- let &BitvSet(ref bitv) = self;
- bitv.capacity()
- }
-
- /// Grows the underlying vector to be able to store `size` bits.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::BitvSet;
- ///
- /// let mut s = BitvSet::new();
- /// s.reserve(10);
- /// assert!(s.capacity() >= 10);
- /// ```
- pub fn reserve(&mut self, size: uint) {
- let &BitvSet(ref mut bitv) = self;
- bitv.reserve(size);
- if bitv.nbits < size {
- bitv.nbits = bitv.capacity();
- }
- }
-
- /// Consumes this set to return the underlying bit vector.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::BitvSet;
- ///
- /// let mut s = BitvSet::new();
- /// s.insert(0);
- /// s.insert(3);
- ///
- /// let bv = s.into_bitv();
- /// assert!(bv.get(0));
- /// assert!(bv.get(3));
- /// ```
- #[inline]
- pub fn into_bitv(self) -> Bitv {
- let BitvSet(bitv) = self;
- bitv
- }
-
- /// Returns a reference to the underlying bit vector.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::BitvSet;
- ///
- /// let mut s = BitvSet::new();
- /// s.insert(0);
- ///
- /// let bv = s.get_ref();
- /// assert_eq!(bv[0], true);
- /// ```
- #[inline]
- pub fn get_ref<'a>(&'a self) -> &'a Bitv {
- let &BitvSet(ref bitv) = self;
- bitv
- }
-
- #[inline]
- fn other_op(&mut self, other: &BitvSet, f: |u32, u32| -> u32) {
- // Expand the vector if necessary
- self.reserve(other.capacity());
-
- // Unwrap Bitvs
- let &BitvSet(ref mut self_bitv) = self;
- let &BitvSet(ref other_bitv) = other;
-
- // virtually pad other with 0's for equal lengths
- let mut other_words = {
- let (_, result) = match_words(self_bitv, other_bitv);
- result
- };
-
- // Apply values found in other
- for (i, w) in other_words {
- let old = self_bitv.storage[i];
- let new = f(old, w);
- self_bitv.storage[i] = new;
- }
- }
-
- /// Truncates the underlying vector to the least length required.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::BitvSet;
- ///
- /// let mut s = BitvSet::new();
- /// s.insert(32183231);
- /// s.remove(&32183231);
- ///
- /// // Internal storage will probably be bigger than necessary
- /// println!("old capacity: {}", s.capacity());
- ///
- /// // Now should be smaller
- /// s.shrink_to_fit();
- /// println!("new capacity: {}", s.capacity());
- /// ```
- #[inline]
- pub fn shrink_to_fit(&mut self) {
- let &BitvSet(ref mut bitv) = self;
- // Obtain original length
- let old_len = bitv.storage.len();
- // Obtain coarse trailing zero length
- let n = bitv.storage.iter().rev().take_while(|&&n| n == 0).count();
- // Truncate
- let trunc_len = cmp::max(old_len - n, 1);
- bitv.storage.truncate(trunc_len);
- bitv.nbits = trunc_len * u32::BITS;
- }
-
- /// Iterator over each u32 stored in the `BitvSet`.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::BitvSet;
- /// use std::collections::bitv;
- ///
- /// let s = BitvSet::from_bitv(bitv::from_bytes([0b01001010]));
- ///
- /// // Print 1, 4, 6 in arbitrary order
- /// for x in s.iter() {
- /// println!("{}", x);
- /// }
- /// ```
- #[inline]
- pub fn iter<'a>(&'a self) -> BitPositions<'a> {
- BitPositions {set: self, next_idx: 0u}
- }
-
- /// Iterator over each u32 stored in `self` union `other`.
- /// See [union_with](#method.union_with) for an efficient in-place version.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::BitvSet;
- /// use std::collections::bitv;
- ///
- /// let a = BitvSet::from_bitv(bitv::from_bytes([0b01101000]));
- /// let b = BitvSet::from_bitv(bitv::from_bytes([0b10100000]));
- ///
- /// // Print 0, 1, 2, 4 in arbitrary order
- /// for x in a.union(&b) {
- /// println!("{}", x);
- /// }
- /// ```
- #[inline]
- pub fn union<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
- TwoBitPositions {
- set: self,
- other: other,
- merge: |w1, w2| w1 | w2,
- current_word: 0u32,
- next_idx: 0u
- }
- }
-
- /// Iterator over each uint stored in `self` intersect `other`.
- /// See [intersect_with](#method.intersect_with) for an efficient in-place version.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::BitvSet;
- /// use std::collections::bitv;
- ///
- /// let a = BitvSet::from_bitv(bitv::from_bytes([0b01101000]));
- /// let b = BitvSet::from_bitv(bitv::from_bytes([0b10100000]));
- ///
- /// // Print 2
- /// for x in a.intersection(&b) {
- /// println!("{}", x);
- /// }
- /// ```
- #[inline]
- pub fn intersection<'a>(&'a self, other: &'a BitvSet) -> Take<TwoBitPositions<'a>> {
- let min = cmp::min(self.capacity(), other.capacity());
- TwoBitPositions {
- set: self,
- other: other,
- merge: |w1, w2| w1 & w2,
- current_word: 0u32,
- next_idx: 0
- }.take(min)
- }
-
- /// Iterator over each uint stored in the `self` setminus `other`.
- /// See [difference_with](#method.difference_with) for an efficient in-place version.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::BitvSet;
- /// use std::collections::bitv;
- ///
- /// let a = BitvSet::from_bitv(bitv::from_bytes([0b01101000]));
- /// let b = BitvSet::from_bitv(bitv::from_bytes([0b10100000]));
- ///
- /// // Print 1, 4 in arbitrary order
- /// for x in a.difference(&b) {
- /// println!("{}", x);
- /// }
- ///
- /// // Note that difference is not symmetric,
- /// // and `b - a` means something else.
- /// // This prints 0
- /// for x in b.difference(&a) {
- /// println!("{}", x);
- /// }
- /// ```
- #[inline]
- pub fn difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
- TwoBitPositions {
- set: self,
- other: other,
- merge: |w1, w2| w1 & !w2,
- current_word: 0u32,
- next_idx: 0
- }
- }
-
- /// Iterator over each u32 stored in the symmetric difference of `self` and `other`.
- /// See [symmetric_difference_with](#method.symmetric_difference_with) for
- /// an efficient in-place version.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::BitvSet;
- /// use std::collections::bitv;
- ///
- /// let a = BitvSet::from_bitv(bitv::from_bytes([0b01101000]));
- /// let b = BitvSet::from_bitv(bitv::from_bytes([0b10100000]));
- ///
- /// // Print 0, 1, 4 in arbitrary order
- /// for x in a.symmetric_difference(&b) {
- /// println!("{}", x);
- /// }
- /// ```
- #[inline]
- pub fn symmetric_difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
- TwoBitPositions {
- set: self,
- other: other,
- merge: |w1, w2| w1 ^ w2,
- current_word: 0u32,
- next_idx: 0
- }
- }
-
- /// Unions in-place with the specified other bit vector.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::BitvSet;
- /// use std::collections::bitv;
- ///
- /// let a = 0b01101000;
- /// let b = 0b10100000;
- /// let res = 0b11101000;
- ///
- /// let mut a = BitvSet::from_bitv(bitv::from_bytes([a]));
- /// let b = BitvSet::from_bitv(bitv::from_bytes([b]));
- /// let res = BitvSet::from_bitv(bitv::from_bytes([res]));
- ///
- /// a.union_with(&b);
- /// assert_eq!(a, res);
- /// ```
- #[inline]
- pub fn union_with(&mut self, other: &BitvSet) {
- self.other_op(other, |w1, w2| w1 | w2);
- }
-
- /// Intersects in-place with the specified other bit vector.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::BitvSet;
- /// use std::collections::bitv;
- ///
- /// let a = 0b01101000;
- /// let b = 0b10100000;
- /// let res = 0b00100000;
- ///
- /// let mut a = BitvSet::from_bitv(bitv::from_bytes([a]));
- /// let b = BitvSet::from_bitv(bitv::from_bytes([b]));
- /// let res = BitvSet::from_bitv(bitv::from_bytes([res]));
- ///
- /// a.intersect_with(&b);
- /// assert_eq!(a, res);
- /// ```
- #[inline]
- pub fn intersect_with(&mut self, other: &BitvSet) {
- self.other_op(other, |w1, w2| w1 & w2);
- }
-
- /// Makes this bit vector the difference with the specified other bit vector
- /// in-place.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::BitvSet;
- /// use std::collections::bitv;
- ///
- /// let a = 0b01101000;
- /// let b = 0b10100000;
- /// let a_b = 0b01001000; // a - b
- /// let b_a = 0b10000000; // b - a
- ///
- /// let mut bva = BitvSet::from_bitv(bitv::from_bytes([a]));
- /// let bvb = BitvSet::from_bitv(bitv::from_bytes([b]));
- /// let bva_b = BitvSet::from_bitv(bitv::from_bytes([a_b]));
- /// let bvb_a = BitvSet::from_bitv(bitv::from_bytes([b_a]));
- ///
- /// bva.difference_with(&bvb);
- /// assert_eq!(bva, bva_b);
- ///
- /// let bva = BitvSet::from_bitv(bitv::from_bytes([a]));
- /// let mut bvb = BitvSet::from_bitv(bitv::from_bytes([b]));
- ///
- /// bvb.difference_with(&bva);
- /// assert_eq!(bvb, bvb_a);
- /// ```
- #[inline]
- pub fn difference_with(&mut self, other: &BitvSet) {
- self.other_op(other, |w1, w2| w1 & !w2);
- }
-
- /// Makes this bit vector the symmetric difference with the specified other
- /// bit vector in-place.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::BitvSet;
- /// use std::collections::bitv;
- ///
- /// let a = 0b01101000;
- /// let b = 0b10100000;
- /// let res = 0b11001000;
- ///
- /// let mut a = BitvSet::from_bitv(bitv::from_bytes([a]));
- /// let b = BitvSet::from_bitv(bitv::from_bytes([b]));
- /// let res = BitvSet::from_bitv(bitv::from_bytes([res]));
- ///
- /// a.symmetric_difference_with(&b);
- /// assert_eq!(a, res);
- /// ```
- #[inline]
- pub fn symmetric_difference_with(&mut self, other: &BitvSet) {
- self.other_op(other, |w1, w2| w1 ^ w2);
- }
-
- /// Return the number of set bits in this set.
- #[inline]
- pub fn len(&self) -> uint {
- let &BitvSet(ref bitv) = self;
- bitv.storage.iter().fold(0, |acc, &n| acc + n.count_ones())
- }
-
- /// Returns whether there are no bits set in this set
- #[inline]
- pub fn is_empty(&self) -> bool {
- let &BitvSet(ref bitv) = self;
- bitv.storage.iter().all(|&n| n == 0)
- }
-
- /// Clears all bits in this set
- #[inline]
- pub fn clear(&mut self) {
- let &BitvSet(ref mut bitv) = self;
- bitv.clear();
- }
-
- /// Returns `true` if this set contains the specified integer.
- #[inline]
- pub fn contains(&self, value: &uint) -> bool {
- let &BitvSet(ref bitv) = self;
- *value < bitv.nbits && bitv.get(*value)
- }
-
- /// Returns `true` if the set has no elements in common with `other`.
- /// This is equivalent to checking for an empty intersection.
- #[inline]
- pub fn is_disjoint(&self, other: &BitvSet) -> bool {
- self.intersection(other).next().is_none()
- }
-
- /// Returns `true` if the set is a subset of another.
- #[inline]
- pub fn is_subset(&self, other: &BitvSet) -> bool {
- let &BitvSet(ref self_bitv) = self;
- let &BitvSet(ref other_bitv) = other;
-
- // Check that `self` intersect `other` is self
- self_bitv.mask_words(0).zip(other_bitv.mask_words(0))
- .all(|((_, w1), (_, w2))| w1 & w2 == w1) &&
- // Check that `self` setminus `other` is empty
- self_bitv.mask_words(other_bitv.storage.len()).all(|(_, w)| w == 0)
- }
-
- /// Returns `true` if the set is a superset of another.
- #[inline]
- pub fn is_superset(&self, other: &BitvSet) -> bool {
- other.is_subset(self)
- }
-
- /// Adds a value to the set. Returns `true` if the value was not already
- /// present in the set.
- pub fn insert(&mut self, value: uint) -> bool {
- if self.contains(&value) {
- return false;
- }
-
- // Ensure we have enough space to hold the new element
- if value >= self.capacity() {
- let new_cap = cmp::max(value + 1, self.capacity() * 2);
- self.reserve(new_cap);
- }
-
- let &BitvSet(ref mut bitv) = self;
- bitv.set(value, true);
- return true;
- }
-
- /// Removes a value from the set. Returns `true` if the value was
- /// present in the set.
- pub fn remove(&mut self, value: &uint) -> bool {
- if !self.contains(value) {
- return false;
- }
- let &BitvSet(ref mut bitv) = self;
- bitv.set(*value, false);
- return true;
- }
-}
-
-impl fmt::Show for BitvSet {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- try!(write!(fmt, "{{"));
- let mut first = true;
- for n in self.iter() {
- if !first {
- try!(write!(fmt, ", "));
- }
- try!(write!(fmt, "{}", n));
- first = false;
- }
- write!(fmt, "}}")
- }
-}
-
-impl<S: hash::Writer> hash::Hash<S> for BitvSet {
- fn hash(&self, state: &mut S) {
- for pos in self.iter() {
- pos.hash(state);
- }
- }
-}
-
-/// An iterator for `BitvSet`.
-pub struct BitPositions<'a> {
- set: &'a BitvSet,
- next_idx: uint
-}
-
-/// An iterator combining two `BitvSet` iterators.
-pub struct TwoBitPositions<'a> {
- set: &'a BitvSet,
- other: &'a BitvSet,
- merge: |u32, u32|: 'a -> u32,
- current_word: u32,
- next_idx: uint
-}
-
-impl<'a> Iterator<uint> for BitPositions<'a> {
- fn next(&mut self) -> Option<uint> {
- while self.next_idx < self.set.capacity() {
- let idx = self.next_idx;
- self.next_idx += 1;
-
- if self.set.contains(&idx) {
- return Some(idx);
- }
- }
-
- return None;
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- (0, Some(self.set.capacity() - self.next_idx))
- }
-}
-
-impl<'a> Iterator<uint> for TwoBitPositions<'a> {
- fn next(&mut self) -> Option<uint> {
- while self.next_idx < self.set.capacity() ||
- self.next_idx < self.other.capacity() {
- let bit_idx = self.next_idx % u32::BITS;
- if bit_idx == 0 {
- let &BitvSet(ref s_bitv) = self.set;
- let &BitvSet(ref o_bitv) = self.other;
- // Merging the two words is a bit of an awkward dance since
- // one Bitv might be longer than the other
- let word_idx = self.next_idx / u32::BITS;
- let w1 = if word_idx < s_bitv.storage.len() {
- s_bitv.storage[word_idx]
- } else { 0 };
- let w2 = if word_idx < o_bitv.storage.len() {
- o_bitv.storage[word_idx]
- } else { 0 };
- self.current_word = (self.merge)(w1, w2);
- }
-
- self.next_idx += 1;
- if self.current_word & (1 << bit_idx) != 0 {
- return Some(self.next_idx - 1);
- }
- }
- return None;
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- let cap = cmp::max(self.set.capacity(), self.other.capacity());
- (0, Some(cap - self.next_idx))
- }
-}
-
-#[cfg(test)]
-mod tests {
- use std::prelude::*;
- use std::iter::range_step;
- use std::u32;
- use std::rand;
- use std::rand::Rng;
- use test::Bencher;
-
- use bitv::{Bitv, BitvSet, from_fn, from_bytes};
- use bitv;
- use vec::Vec;
-
- static BENCH_BITS : uint = 1 << 14;
-
- #[test]
- fn test_to_str() {
- let zerolen = Bitv::new();
- assert_eq!(zerolen.to_string().as_slice(), "");
-
- let eightbits = Bitv::with_capacity(8u, false);
- assert_eq!(eightbits.to_string().as_slice(), "00000000")
- }
-
- #[test]
- fn test_0_elements() {
- let act = Bitv::new();
- let exp = Vec::from_elem(0u, false);
- assert!(act.eq_vec(exp.as_slice()));
- }
-
- #[test]
- fn test_1_element() {
- let mut act = Bitv::with_capacity(1u, false);
- assert!(act.eq_vec([false]));
- act = Bitv::with_capacity(1u, true);
- assert!(act.eq_vec([true]));
- }
-
- #[test]
- fn test_2_elements() {
- let mut b = bitv::Bitv::with_capacity(2, false);
- b.set(0, true);
- b.set(1, false);
- assert_eq!(b.to_string().as_slice(), "10");
- }
-
- #[test]
- fn test_10_elements() {
- let mut act;
- // all 0
-
- act = Bitv::with_capacity(10u, false);
- assert!((act.eq_vec(
- [false, false, false, false, false, false, false, false, false, false])));
- // all 1
-
- act = Bitv::with_capacity(10u, true);
- assert!((act.eq_vec([true, true, true, true, true, true, true, true, true, true])));
- // mixed
-
- act = Bitv::with_capacity(10u, false);
- act.set(0u, true);
- act.set(1u, true);
- act.set(2u, true);
- act.set(3u, true);
- act.set(4u, true);
- assert!((act.eq_vec([true, true, true, true, true, false, false, false, false, false])));
- // mixed
-
- act = Bitv::with_capacity(10u, false);
- act.set(5u, true);
- act.set(6u, true);
- act.set(7u, true);
- act.set(8u, true);
- act.set(9u, true);
- assert!((act.eq_vec([false, false, false, false, false, true, true, true, true, true])));
- // mixed
-
- act = Bitv::with_capacity(10u, false);
- act.set(0u, true);
- act.set(3u, true);
- act.set(6u, true);
- act.set(9u, true);
- assert!((act.eq_vec([true, false, false, true, false, false, true, false, false, true])));
- }
-
- #[test]
- fn test_31_elements() {
- let mut act;
- // all 0
-
- act = Bitv::with_capacity(31u, false);
- assert!(act.eq_vec(
- [false, false, false, false, false, false, false, false, false, false, false,
- false, false, false, false, false, false, false, false, false, false, false, false,
- false, false, false, false, false, false, false, false]));
- // all 1
-
- act = Bitv::with_capacity(31u, true);
- assert!(act.eq_vec(
- [true, true, true, true, true, true, true, true, true, true, true, true, true,
- true, true, true, true, true, true, true, true, true, true, true, true, true, true,
- true, true, true, true]));
- // mixed
-
- act = Bitv::with_capacity(31u, false);
- act.set(0u, true);
- act.set(1u, true);
- act.set(2u, true);
- act.set(3u, true);
- act.set(4u, true);
- act.set(5u, true);
- act.set(6u, true);
- act.set(7u, true);
- assert!(act.eq_vec(
- [true, true, true, true, true, true, true, true, false, false, false, false, false,
- false, false, false, false, false, false, false, false, false, false, false, false,
- false, false, false, false, false, false]));
- // mixed
-
- act = Bitv::with_capacity(31u, false);
- act.set(16u, true);
- act.set(17u, true);
- act.set(18u, true);
- act.set(19u, true);
- act.set(20u, true);
- act.set(21u, true);
- act.set(22u, true);
- act.set(23u, true);
- assert!(act.eq_vec(
- [false, false, false, false, false, false, false, false, false, false, false,
- false, false, false, false, false, true, true, true, true, true, true, true, true,
- false, false, false, false, false, false, false]));
- // mixed
-
- act = Bitv::with_capacity(31u, false);
- act.set(24u, true);
- act.set(25u, true);
- act.set(26u, true);
- act.set(27u, true);
- act.set(28u, true);
- act.set(29u, true);
- act.set(30u, true);
- assert!(act.eq_vec(
- [false, false, false, false, false, false, false, false, false, false, false,
- false, false, false, false, false, false, false, false, false, false, false, false,
- false, true, true, true, true, true, true, true]));
- // mixed
-
- act = Bitv::with_capacity(31u, false);
- act.set(3u, true);
- act.set(17u, true);
- act.set(30u, true);
- assert!(act.eq_vec(
- [false, false, false, true, false, false, false, false, false, false, false, false,
- false, false, false, false, false, true, false, false, false, false, false, false,
- false, false, false, false, false, false, true]));
- }
-
- #[test]
- fn test_32_elements() {
- let mut act;
- // all 0
-
- act = Bitv::with_capacity(32u, false);
- assert!(act.eq_vec(
- [false, false, false, false, false, false, false, false, false, false, false,
- false, false, false, false, false, false, false, false, false, false, false, false,
- false, false, false, false, false, false, false, false, false]));
- // all 1
-
- act = Bitv::with_capacity(32u, true);
- assert!(act.eq_vec(
- [true, true, true, true, true, true, true, true, true, true, true, true, true,
- true, true, true, true, true, true, true, true, true, true, true, true, true, true,
- true, true, true, true, true]));
- // mixed
-
- act = Bitv::with_capacity(32u, false);
- act.set(0u, true);
- act.set(1u, true);
- act.set(2u, true);
- act.set(3u, true);
- act.set(4u, true);
- act.set(5u, true);
- act.set(6u, true);
- act.set(7u, true);
- assert!(act.eq_vec(
- [true, true, true, true, true, true, true, true, false, false, false, false, false,
- false, false, false, false, false, false, false, false, false, false, false, false,
- false, false, false, false, false, false, false]));
- // mixed
-
- act = Bitv::with_capacity(32u, false);
- act.set(16u, true);
- act.set(17u, true);
- act.set(18u, true);
- act.set(19u, true);
- act.set(20u, true);
- act.set(21u, true);
- act.set(22u, true);
- act.set(23u, true);
- assert!(act.eq_vec(
- [false, false, false, false, false, false, false, false, false, false, false,
- false, false, false, false, false, true, true, true, true, true, true, true, true,
- false, false, false, false, false, false, false, false]));
- // mixed
-
- act = Bitv::with_capacity(32u, false);
- act.set(24u, true);
- act.set(25u, true);
- act.set(26u, true);
- act.set(27u, true);
- act.set(28u, true);
- act.set(29u, true);
- act.set(30u, true);
- act.set(31u, true);
- assert!(act.eq_vec(
- [false, false, false, false, false, false, false, false, false, false, false,
- false, false, false, false, false, false, false, false, false, false, false, false,
- false, true, true, true, true, true, true, true, true]));
- // mixed
-
- act = Bitv::with_capacity(32u, false);
- act.set(3u, true);
- act.set(17u, true);
- act.set(30u, true);
- act.set(31u, true);
- assert!(act.eq_vec(
- [false, false, false, true, false, false, false, false, false, false, false, false,
- false, false, false, false, false, true, false, false, false, false, false, false,
- false, false, false, false, false, false, true, true]));
- }
-
- #[test]
- fn test_33_elements() {
- let mut act;
- // all 0
-
- act = Bitv::with_capacity(33u, false);
- assert!(act.eq_vec(
- [false, false, false, false, false, false, false, false, false, false, false,
- false, false, false, false, false, false, false, false, false, false, false, false,
- false, false, false, false, false, false, false, false, false, false]));
- // all 1
-
- act = Bitv::with_capacity(33u, true);
- assert!(act.eq_vec(
- [true, true, true, true, true, true, true, true, true, true, true, true, true,
- true, true, true, true, true, true, true, true, true, true, true, true, true, true,
- true, true, true, true, true, true]));
- // mixed
-
- act = Bitv::with_capacity(33u, false);
- act.set(0u, true);
- act.set(1u, true);
- act.set(2u, true);
- act.set(3u, true);
- act.set(4u, true);
- act.set(5u, true);
- act.set(6u, true);
- act.set(7u, true);
- assert!(act.eq_vec(
- [true, true, true, true, true, true, true, true, false, false, false, false, false,
- false, false, false, false, false, false, false, false, false, false, false, false,
- false, false, false, false, false, false, false, false]));
- // mixed
-
- act = Bitv::with_capacity(33u, false);
- act.set(16u, true);
- act.set(17u, true);
- act.set(18u, true);
- act.set(19u, true);
- act.set(20u, true);
- act.set(21u, true);
- act.set(22u, true);
- act.set(23u, true);
- assert!(act.eq_vec(
- [false, false, false, false, false, false, false, false, false, false, false,
- false, false, false, false, false, true, true, true, true, true, true, true, true,
- false, false, false, false, false, false, false, false, false]));
- // mixed
-
- act = Bitv::with_capacity(33u, false);
- act.set(24u, true);
- act.set(25u, true);
- act.set(26u, true);
- act.set(27u, true);
- act.set(28u, true);
- act.set(29u, true);
- act.set(30u, true);
- act.set(31u, true);
- assert!(act.eq_vec(
- [false, false, false, false, false, false, false, false, false, false, false,
- false, false, false, false, false, false, false, false, false, false, false, false,
- false, true, true, true, true, true, true, true, true, false]));
- // mixed
-
- act = Bitv::with_capacity(33u, false);
- act.set(3u, true);
- act.set(17u, true);
- act.set(30u, true);
- act.set(31u, true);
- act.set(32u, true);
- assert!(act.eq_vec(
- [false, false, false, true, false, false, false, false, false, false, false, false,
- false, false, false, false, false, true, false, false, false, false, false, false,
- false, false, false, false, false, false, true, true, true]));
- }
-
- #[test]
- fn test_equal_differing_sizes() {
- let v0 = Bitv::with_capacity(10u, false);
- let v1 = Bitv::with_capacity(11u, false);
- assert!(v0 != v1);
- }
-
- #[test]
- fn test_equal_greatly_differing_sizes() {
- let v0 = Bitv::with_capacity(10u, false);
- let v1 = Bitv::with_capacity(110u, false);
- assert!(v0 != v1);
- }
-
- #[test]
- fn test_equal_sneaky_small() {
- let mut a = bitv::Bitv::with_capacity(1, false);
- a.set(0, true);
-
- let mut b = bitv::Bitv::with_capacity(1, true);
- b.set(0, true);
-
- assert_eq!(a, b);
- }
-
- #[test]
- fn test_equal_sneaky_big() {
- let mut a = bitv::Bitv::with_capacity(100, false);
- for i in range(0u, 100) {
- a.set(i, true);
- }
-
- let mut b = bitv::Bitv::with_capacity(100, true);
- for i in range(0u, 100) {
- b.set(i, true);
- }
-
- assert_eq!(a, b);
- }
-
- #[test]
- fn test_from_bytes() {
- let bitv = from_bytes([0b10110110, 0b00000000, 0b11111111]);
- let str = format!("{}{}{}", "10110110", "00000000", "11111111");
- assert_eq!(bitv.to_string().as_slice(), str.as_slice());
- }
-
- #[test]
- fn test_to_bytes() {
- let mut bv = Bitv::with_capacity(3, true);
- bv.set(1, false);
- assert_eq!(bv.to_bytes(), vec!(0b10100000));
-
- let mut bv = Bitv::with_capacity(9, false);
- bv.set(2, true);
- bv.set(8, true);
- assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000));
- }
-
- #[test]
- fn test_from_bools() {
- let bools = vec![true, false, true, true];
- let bitv: Bitv = bools.iter().map(|n| *n).collect();
- assert_eq!(bitv.to_string().as_slice(), "1011");
- }
-
- #[test]
- fn test_bitv_set_from_bools() {
- let bools = vec![true, false, true, true];
- let a: BitvSet = bools.iter().map(|n| *n).collect();
- let mut b = BitvSet::new();
- b.insert(0);
- b.insert(2);
- b.insert(3);
- assert_eq!(a, b);
- }
-
- #[test]
- fn test_to_bools() {
- let bools = vec!(false, false, true, false, false, true, true, false);
- assert_eq!(from_bytes([0b00100110]).iter().collect::<Vec<bool>>(), bools);
- }
-
- #[test]
- fn test_bitv_iterator() {
- let bools = vec![true, false, true, true];
- let bitv: Bitv = bools.iter().map(|n| *n).collect();
-
- assert_eq!(bitv.iter().collect::<Vec<bool>>(), bools)
-
- let long = Vec::from_fn(10000, |i| i % 2 == 0);
- let bitv: Bitv = long.iter().map(|n| *n).collect();
- assert_eq!(bitv.iter().collect::<Vec<bool>>(), long)
- }
-
- #[test]
- fn test_bitv_set_iterator() {
- let bools = [true, false, true, true];
- let bitv: BitvSet = bools.iter().map(|n| *n).collect();
-
- let idxs: Vec<uint> = bitv.iter().collect();
- assert_eq!(idxs, vec!(0, 2, 3));
-
- let long: BitvSet = range(0u, 10000).map(|n| n % 2 == 0).collect();
- let real = range_step(0, 10000, 2).collect::<Vec<uint>>();
-
- let idxs: Vec<uint> = long.iter().collect();
- assert_eq!(idxs, real);
- }
-
- #[test]
- fn test_bitv_set_frombitv_init() {
- let bools = [true, false];
- let lengths = [10, 64, 100];
- for &b in bools.iter() {
- for &l in lengths.iter() {
- let bitset = BitvSet::from_bitv(Bitv::with_capacity(l, b));
- assert_eq!(bitset.contains(&1u), b)
- assert_eq!(bitset.contains(&(l-1u)), b)
- assert!(!bitset.contains(&l))
- }
- }
- }
-
- #[test]
- fn test_small_difference() {
- let mut b1 = Bitv::with_capacity(3, false);
- let mut b2 = Bitv::with_capacity(3, false);
- b1.set(0, true);
- b1.set(1, true);
- b2.set(1, true);
- b2.set(2, true);
- assert!(b1.difference(&b2));
- assert!(b1.get(0));
- assert!(!b1.get(1));
- assert!(!b1.get(2));
- }
-
- #[test]
- fn test_big_difference() {
- let mut b1 = Bitv::with_capacity(100, false);
- let mut b2 = Bitv::with_capacity(100, false);
- b1.set(0, true);
- b1.set(40, true);
- b2.set(40, true);
- b2.set(80, true);
- assert!(b1.difference(&b2));
- assert!(b1.get(0));
- assert!(!b1.get(40));
- assert!(!b1.get(80));
- }
-
- #[test]
- fn test_small_clear() {
- let mut b = Bitv::with_capacity(14, true);
- b.clear();
- assert!(b.none());
- }
-
- #[test]
- fn test_big_clear() {
- let mut b = Bitv::with_capacity(140, true);
- b.clear();
- assert!(b.none());
- }
-
- #[test]
- fn test_bitv_masking() {
- let b = Bitv::with_capacity(140, true);
- let mut bs = BitvSet::from_bitv(b);
- assert!(bs.contains(&139));
- assert!(!bs.contains(&140));
- assert!(bs.insert(150));
- assert!(!bs.contains(&140));
- assert!(!bs.contains(&149));
- assert!(bs.contains(&150));
- assert!(!bs.contains(&151));
- }
-
- #[test]
- fn test_bitv_set_basic() {
- // calculate nbits with u32::BITS granularity
- fn calc_nbits(bits: uint) -> uint {
- u32::BITS * ((bits + u32::BITS - 1) / u32::BITS)
- }
-
- let mut b = BitvSet::new();
- assert_eq!(b.capacity(), calc_nbits(0));
- assert!(b.insert(3));
- assert_eq!(b.capacity(), calc_nbits(3));
- assert!(!b.insert(3));
- assert!(b.contains(&3));
- assert!(b.insert(4));
- assert!(!b.insert(4));
- assert!(b.contains(&3));
- assert!(b.insert(400));
- assert_eq!(b.capacity(), calc_nbits(400));
- assert!(!b.insert(400));
- assert!(b.contains(&400));
- assert_eq!(b.len(), 3);
- }
-
- #[test]
- fn test_bitv_set_intersection() {
- let mut a = BitvSet::new();
- let mut b = BitvSet::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!(b.insert(2));
- assert!(b.insert(11));
- assert!(b.insert(77));
- assert!(b.insert(5));
- assert!(b.insert(3));
-
- let expected = [3, 5, 11, 77];
- let actual = a.intersection(&b).collect::<Vec<uint>>();
- assert_eq!(actual.as_slice(), expected.as_slice());
- }
-
- #[test]
- fn test_bitv_set_difference() {
- let mut a = BitvSet::new();
- let mut b = BitvSet::new();
-
- assert!(a.insert(1));
- assert!(a.insert(3));
- assert!(a.insert(5));
- assert!(a.insert(200));
- assert!(a.insert(500));
-
- assert!(b.insert(3));
- assert!(b.insert(200));
-
- let expected = [1, 5, 500];
- let actual = a.difference(&b).collect::<Vec<uint>>();
- assert_eq!(actual.as_slice(), expected.as_slice());
- }
-
- #[test]
- fn test_bitv_set_symmetric_difference() {
- let mut a = BitvSet::new();
- let mut b = BitvSet::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));
- assert!(b.insert(14));
- assert!(b.insert(220));
-
- let expected = [1, 5, 11, 14, 220];
- let actual = a.symmetric_difference(&b).collect::<Vec<uint>>();
- assert_eq!(actual.as_slice(), expected.as_slice());
- }
-
- #[test]
- fn test_bitv_set_union() {
- let mut a = BitvSet::new();
- let mut b = BitvSet::new();
- assert!(a.insert(1));
- assert!(a.insert(3));
- assert!(a.insert(5));
- assert!(a.insert(9));
- assert!(a.insert(11));
- assert!(a.insert(160));
- assert!(a.insert(19));
- assert!(a.insert(24));
- assert!(a.insert(200));
-
- assert!(b.insert(1));
- assert!(b.insert(5));
- assert!(b.insert(9));
- assert!(b.insert(13));
- assert!(b.insert(19));
-
- let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160, 200];
- let actual = a.union(&b).collect::<Vec<uint>>();
- assert_eq!(actual.as_slice(), expected.as_slice());
- }
-
- #[test]
- fn test_bitv_set_subset() {
- let mut set1 = BitvSet::new();
- let mut set2 = BitvSet::new();
-
- assert!(set1.is_subset(&set2)); // {} {}
- set2.insert(100);
- assert!(set1.is_subset(&set2)); // {} { 1 }
- set2.insert(200);
- assert!(set1.is_subset(&set2)); // {} { 1, 2 }
- set1.insert(200);
- assert!(set1.is_subset(&set2)); // { 2 } { 1, 2 }
- set1.insert(300);
- assert!(!set1.is_subset(&set2)); // { 2, 3 } { 1, 2 }
- set2.insert(300);
- assert!(set1.is_subset(&set2)); // { 2, 3 } { 1, 2, 3 }
- set2.insert(400);
- assert!(set1.is_subset(&set2)); // { 2, 3 } { 1, 2, 3, 4 }
- set2.remove(&100);
- assert!(set1.is_subset(&set2)); // { 2, 3 } { 2, 3, 4 }
- set2.remove(&300);
- assert!(!set1.is_subset(&set2)); // { 2, 3 } { 2, 4 }
- set1.remove(&300);
- assert!(set1.is_subset(&set2)); // { 2 } { 2, 4 }
- }
-
- #[test]
- fn test_bitv_set_is_disjoint() {
- let a = BitvSet::from_bitv(from_bytes([0b10100010]));
- let b = BitvSet::from_bitv(from_bytes([0b01000000]));
- let c = BitvSet::new();
- let d = BitvSet::from_bitv(from_bytes([0b00110000]));
-
- assert!(!a.is_disjoint(&d));
- assert!(!d.is_disjoint(&a));
-
- assert!(a.is_disjoint(&b))
- assert!(a.is_disjoint(&c))
- assert!(b.is_disjoint(&a))
- assert!(b.is_disjoint(&c))
- assert!(c.is_disjoint(&a))
- assert!(c.is_disjoint(&b))
- }
-
- #[test]
- fn test_bitv_set_union_with() {
- //a should grow to include larger elements
- let mut a = BitvSet::new();
- a.insert(0);
- let mut b = BitvSet::new();
- b.insert(5);
- let expected = BitvSet::from_bitv(from_bytes([0b10000100]));
- a.union_with(&b);
- assert_eq!(a, expected);
-
- // Standard
- let mut a = BitvSet::from_bitv(from_bytes([0b10100010]));
- let mut b = BitvSet::from_bitv(from_bytes([0b01100010]));
- let c = a.clone();
- a.union_with(&b);
- b.union_with(&c);
- assert_eq!(a.len(), 4);
- assert_eq!(b.len(), 4);
- }
-
- #[test]
- fn test_bitv_set_intersect_with() {
- // Explicitly 0'ed bits
- let mut a = BitvSet::from_bitv(from_bytes([0b10100010]));
- let mut b = BitvSet::from_bitv(from_bytes([0b00000000]));
- let c = a.clone();
- a.intersect_with(&b);
- b.intersect_with(&c);
- assert!(a.is_empty());
- assert!(b.is_empty());
-
- // Uninitialized bits should behave like 0's
- let mut a = BitvSet::from_bitv(from_bytes([0b10100010]));
- let mut b = BitvSet::new();
- let c = a.clone();
- a.intersect_with(&b);
- b.intersect_with(&c);
- assert!(a.is_empty());
- assert!(b.is_empty());
-
- // Standard
- let mut a = BitvSet::from_bitv(from_bytes([0b10100010]));
- let mut b = BitvSet::from_bitv(from_bytes([0b01100010]));
- let c = a.clone();
- a.intersect_with(&b);
- b.intersect_with(&c);
- assert_eq!(a.len(), 2);
- assert_eq!(b.len(), 2);
- }
-
- #[test]
- fn test_bitv_set_difference_with() {
- // Explicitly 0'ed bits
- let mut a = BitvSet::from_bitv(from_bytes([0b00000000]));
- let b = BitvSet::from_bitv(from_bytes([0b10100010]));
- a.difference_with(&b);
- assert!(a.is_empty());
-
- // Uninitialized bits should behave like 0's
- let mut a = BitvSet::new();
- let b = BitvSet::from_bitv(from_bytes([0b11111111]));
- a.difference_with(&b);
- assert!(a.is_empty());
-
- // Standard
- let mut a = BitvSet::from_bitv(from_bytes([0b10100010]));
- let mut b = BitvSet::from_bitv(from_bytes([0b01100010]));
- let c = a.clone();
- a.difference_with(&b);
- b.difference_with(&c);
- assert_eq!(a.len(), 1);
- assert_eq!(b.len(), 1);
- }
-
- #[test]
- fn test_bitv_set_symmetric_difference_with() {
- //a should grow to include larger elements
- let mut a = BitvSet::new();
- a.insert(0);
- a.insert(1);
- let mut b = BitvSet::new();
- b.insert(1);
- b.insert(5);
- let expected = BitvSet::from_bitv(from_bytes([0b10000100]));
- a.symmetric_difference_with(&b);
- assert_eq!(a, expected);
-
- let mut a = BitvSet::from_bitv(from_bytes([0b10100010]));
- let b = BitvSet::new();
- let c = a.clone();
- a.symmetric_difference_with(&b);
- assert_eq!(a, c);
-
- // Standard
- let mut a = BitvSet::from_bitv(from_bytes([0b11100010]));
- let mut b = BitvSet::from_bitv(from_bytes([0b01101010]));
- let c = a.clone();
- a.symmetric_difference_with(&b);
- b.symmetric_difference_with(&c);
- assert_eq!(a.len(), 2);
- assert_eq!(b.len(), 2);
- }
-
- #[test]
- fn test_bitv_set_eq() {
- let a = BitvSet::from_bitv(from_bytes([0b10100010]));
- let b = BitvSet::from_bitv(from_bytes([0b00000000]));
- let c = BitvSet::new();
-
- assert!(a == a);
- assert!(a != b);
- assert!(a != c);
- assert!(b == b);
- assert!(b == c);
- assert!(c == c);
- }
-
- #[test]
- fn test_bitv_set_cmp() {
- let a = BitvSet::from_bitv(from_bytes([0b10100010]));
- let b = BitvSet::from_bitv(from_bytes([0b00000000]));
- let c = BitvSet::new();
-
- assert_eq!(a.cmp(&b), Greater);
- assert_eq!(a.cmp(&c), Greater);
- assert_eq!(b.cmp(&a), Less);
- assert_eq!(b.cmp(&c), Equal);
- assert_eq!(c.cmp(&a), Less);
- assert_eq!(c.cmp(&b), Equal);
- }
-
- #[test]
- fn test_bitv_remove() {
- let mut a = BitvSet::new();
-
- assert!(a.insert(1));
- assert!(a.remove(&1));
-
- assert!(a.insert(100));
- assert!(a.remove(&100));
-
- assert!(a.insert(1000));
- assert!(a.remove(&1000));
- a.shrink_to_fit();
- assert_eq!(a.capacity(), u32::BITS);
- }
-
- #[test]
- fn test_bitv_lt() {
- let mut a = Bitv::with_capacity(5u, false);
- let mut b = Bitv::with_capacity(5u, false);
-
- assert!(!(a < b) && !(b < a));
- b.set(2, true);
- assert!(a < b);
- a.set(3, true);
- assert!(a < b);
- a.set(2, true);
- assert!(!(a < b) && b < a);
- b.set(0, true);
- assert!(a < b);
- }
-
- #[test]
- fn test_ord() {
- let mut a = Bitv::with_capacity(5u, false);
- let mut b = Bitv::with_capacity(5u, false);
-
- assert!(a <= b && a >= b);
- a.set(1, true);
- assert!(a > b && a >= b);
- assert!(b < a && b <= a);
- b.set(1, true);
- b.set(2, true);
- assert!(b > a && b >= a);
- assert!(a < b && a <= b);
- }
-
- #[test]
- fn test_bitv_clone() {
- let mut a = BitvSet::new();
-
- assert!(a.insert(1));
- assert!(a.insert(100));
- assert!(a.insert(1000));
-
- let mut b = a.clone();
-
- assert!(a == b);
-
- assert!(b.remove(&1));
- assert!(a.contains(&1));
-
- assert!(a.remove(&1000));
- assert!(b.contains(&1000));
- }
-
- #[test]
- fn test_small_bitv_tests() {
- let v = from_bytes([0]);
- assert!(!v.all());
- assert!(!v.any());
- assert!(v.none());
-
- let v = from_bytes([0b00010100]);
- assert!(!v.all());
- assert!(v.any());
- assert!(!v.none());
-
- let v = from_bytes([0xFF]);
- assert!(v.all());
- assert!(v.any());
- assert!(!v.none());
- }
-
- #[test]
- fn test_big_bitv_tests() {
- let v = from_bytes([ // 88 bits
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0]);
- assert!(!v.all());
- assert!(!v.any());
- assert!(v.none());
-
- let v = from_bytes([ // 88 bits
- 0, 0, 0b00010100, 0,
- 0, 0, 0, 0b00110100,
- 0, 0, 0]);
- assert!(!v.all());
- assert!(v.any());
- assert!(!v.none());
-
- let v = from_bytes([ // 88 bits
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF]);
- assert!(v.all());
- assert!(v.any());
- assert!(!v.none());
- }
-
- #[test]
- fn test_bitv_push_pop() {
- let mut s = Bitv::with_capacity(5 * u32::BITS - 2, false);
- assert_eq!(s.len(), 5 * u32::BITS - 2);
- assert_eq!(s.get(5 * u32::BITS - 3), false);
- s.push(true);
- s.push(true);
- assert_eq!(s.get(5 * u32::BITS - 2), true);
- assert_eq!(s.get(5 * u32::BITS - 1), true);
- // Here the internal vector will need to be extended
- s.push(false);
- assert_eq!(s.get(5 * u32::BITS), false);
- s.push(false);
- assert_eq!(s.get(5 * u32::BITS + 1), false);
- assert_eq!(s.len(), 5 * u32::BITS + 2);
- // Pop it all off
- assert_eq!(s.pop(), false);
- assert_eq!(s.pop(), false);
- assert_eq!(s.pop(), true);
- assert_eq!(s.pop(), true);
- assert_eq!(s.len(), 5 * u32::BITS - 2);
- }
-
- #[test]
- fn test_bitv_truncate() {
- let mut s = Bitv::with_capacity(5 * u32::BITS, true);
-
- assert_eq!(s, Bitv::with_capacity(5 * u32::BITS, true));
- assert_eq!(s.len(), 5 * u32::BITS);
- s.truncate(4 * u32::BITS);
- assert_eq!(s, Bitv::with_capacity(4 * u32::BITS, true));
- assert_eq!(s.len(), 4 * u32::BITS);
- // Truncating to a size > s.len() should be a noop
- s.truncate(5 * u32::BITS);
- assert_eq!(s, Bitv::with_capacity(4 * u32::BITS, true));
- assert_eq!(s.len(), 4 * u32::BITS);
- s.truncate(3 * u32::BITS - 10);
- assert_eq!(s, Bitv::with_capacity(3 * u32::BITS - 10, true));
- assert_eq!(s.len(), 3 * u32::BITS - 10);
- s.truncate(0);
- assert_eq!(s, Bitv::with_capacity(0, true));
- assert_eq!(s.len(), 0);
- }
-
- #[test]
- fn test_bitv_reserve() {
- let mut s = Bitv::with_capacity(5 * u32::BITS, true);
- // Check capacity
- assert_eq!(s.capacity(), 5 * u32::BITS);
- s.reserve(2 * u32::BITS);
- assert_eq!(s.capacity(), 5 * u32::BITS);
- s.reserve(7 * u32::BITS);
- assert_eq!(s.capacity(), 7 * u32::BITS);
- s.reserve(7 * u32::BITS);
- assert_eq!(s.capacity(), 7 * u32::BITS);
- s.reserve(7 * u32::BITS + 1);
- assert_eq!(s.capacity(), 8 * u32::BITS);
- // Check that length hasn't changed
- assert_eq!(s.len(), 5 * u32::BITS);
- s.push(true);
- s.push(false);
- s.push(true);
- assert_eq!(s.get(5 * u32::BITS - 1), true);
- assert_eq!(s.get(5 * u32::BITS - 0), true);
- assert_eq!(s.get(5 * u32::BITS + 1), false);
- assert_eq!(s.get(5 * u32::BITS + 2), true);
- }
-
- #[test]
- fn test_bitv_grow() {
- let mut bitv = from_bytes([0b10110110, 0b00000000, 0b10101010]);
- bitv.grow(32, true);
- assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b10101010,
- 0xFF, 0xFF, 0xFF, 0xFF]));
- bitv.grow(64, false);
- assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b10101010,
- 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0]));
- bitv.grow(16, true);
- assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b10101010,
- 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]));
- }
-
- #[test]
- fn test_bitv_extend() {
- let mut bitv = from_bytes([0b10110110, 0b00000000, 0b11111111]);
- let ext = from_bytes([0b01001001, 0b10010010, 0b10111101]);
- bitv.extend(ext.iter());
- assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b11111111,
- 0b01001001, 0b10010010, 0b10111101]));
- }
-
- #[test]
- fn test_bitv_set_show() {
- let mut s = BitvSet::new();
- s.insert(1);
- s.insert(10);
- s.insert(50);
- s.insert(2);
- assert_eq!("{1, 2, 10, 50}".to_string(), s.to_string());
- }
-
- fn rng() -> rand::IsaacRng {
- let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
- rand::SeedableRng::from_seed(seed)
- }
-
- #[bench]
- fn bench_uint_small(b: &mut Bencher) {
- let mut r = rng();
- let mut bitv = 0 as uint;
- b.iter(|| {
- for _ in range(0u, 100) {
- bitv |= 1 << ((r.next_u32() as uint) % u32::BITS);
- }
- &bitv
- })
- }
-
- #[bench]
- fn bench_bitv_set_big_fixed(b: &mut Bencher) {
- let mut r = rng();
- let mut bitv = Bitv::with_capacity(BENCH_BITS, false);
- b.iter(|| {
- for _ in range(0u, 100) {
- bitv.set((r.next_u32() as uint) % BENCH_BITS, true);
- }
- &bitv
- })
- }
-
- #[bench]
- fn bench_bitv_set_big_variable(b: &mut Bencher) {
- let mut r = rng();
- let mut bitv = Bitv::with_capacity(BENCH_BITS, false);
- b.iter(|| {
- for _ in range(0u, 100) {
- bitv.set((r.next_u32() as uint) % BENCH_BITS, r.gen());
- }
- &bitv
- })
- }
-
- #[bench]
- fn bench_bitv_set_small(b: &mut Bencher) {
- let mut r = rng();
- let mut bitv = Bitv::with_capacity(u32::BITS, false);
- b.iter(|| {
- for _ in range(0u, 100) {
- bitv.set((r.next_u32() as uint) % u32::BITS, true);
- }
- &bitv
- })
- }
-
- #[bench]
- fn bench_bitvset_small(b: &mut Bencher) {
- let mut r = rng();
- let mut bitv = BitvSet::new();
- b.iter(|| {
- for _ in range(0u, 100) {
- bitv.insert((r.next_u32() as uint) % u32::BITS);
- }
- &bitv
- })
- }
-
- #[bench]
- fn bench_bitvset_big(b: &mut Bencher) {
- let mut r = rng();
- let mut bitv = BitvSet::new();
- b.iter(|| {
- for _ in range(0u, 100) {
- bitv.insert((r.next_u32() as uint) % BENCH_BITS);
- }
- &bitv
- })
- }
-
- #[bench]
- fn bench_bitv_big_union(b: &mut Bencher) {
- let mut b1 = Bitv::with_capacity(BENCH_BITS, false);
- let b2 = Bitv::with_capacity(BENCH_BITS, false);
- b.iter(|| {
- b1.union(&b2)
- })
- }
-
- #[bench]
- fn bench_bitv_small_iter(b: &mut Bencher) {
- let bitv = Bitv::with_capacity(u32::BITS, false);
- b.iter(|| {
- let mut sum = 0u;
- for _ in range(0u, 10) {
- for pres in bitv.iter() {
- sum += pres as uint;
- }
- }
- sum
- })
- }
-
- #[bench]
- fn bench_bitv_big_iter(b: &mut Bencher) {
- let bitv = Bitv::with_capacity(BENCH_BITS, false);
- b.iter(|| {
- let mut sum = 0u;
- for pres in bitv.iter() {
- sum += pres as uint;
- }
- sum
- })
- }
-
- #[bench]
- fn bench_bitvset_iter(b: &mut Bencher) {
- let bitv = BitvSet::from_bitv(from_fn(BENCH_BITS,
- |idx| {idx % 3 == 0}));
- b.iter(|| {
- let mut sum = 0u;
- for idx in bitv.iter() {
- sum += idx as uint;
- }
- sum
- })
- }
-}
use core::{iter, fmt, mem};
use core::fmt::Show;
-use ringbuf::RingBuf;
+use ring_buf::RingBuf;
/// A map based on a B-Tree.
///
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-pub use self::map::BTreeMap;
-pub use self::map::Entries;
-pub use self::map::MutEntries;
-pub use self::map::MoveEntries;
-pub use self::map::Keys;
-pub use self::map::Values;
-pub use self::map::Entry;
-pub use self::map::Occupied;
-pub use self::map::Vacant;
-pub use self::map::OccupiedEntry;
-pub use self::map::VacantEntry;
-
-pub use self::set::BTreeSet;
-pub use self::set::Items;
-pub use self::set::MoveItems;
-pub use self::set::DifferenceItems;
-pub use self::set::UnionItems;
-pub use self::set::SymDifferenceItems;
-pub use self::set::IntersectionItems;
-
-
mod node;
-mod map;
-mod set;
+pub mod map;
+pub mod set;
use core::prelude::*;
-use super::{BTreeMap, Keys, MoveEntries};
+use btree_map::{BTreeMap, Keys, MoveEntries};
use std::hash::Hash;
use core::default::Default;
use core::{iter, fmt};
use std::prelude::*;
use std::mem;
- use enum_set::{EnumSet, CLike};
+ use super::{EnumSet, CLike};
#[deriving(PartialEq, Show)]
#[repr(uint)]
#[cfg(test)] #[phase(plugin, link)] extern crate std;
#[cfg(test)] #[phase(plugin, link)] extern crate log;
-pub use bitv::{Bitv, BitvSet};
-pub use btree::{BTreeMap, BTreeSet};
+
+pub use binary_heap::BinaryHeap;
+pub use bitv::Bitv;
+pub use bitv_set::BitvSet;
+pub use btree_map::BTreeMap;
+pub use btree_set::BTreeSet;
pub use dlist::DList;
pub use enum_set::EnumSet;
-pub use priority_queue::PriorityQueue;
-pub use ringbuf::RingBuf;
-pub use smallintmap::SmallIntMap;
+pub use ring_buf::RingBuf;
pub use string::String;
-pub use treemap::{TreeMap, TreeSet};
-pub use trie::{TrieMap, TrieSet};
+pub use tree_map::TreeMap;
+pub use tree_set::TreeSet;
+pub use trie_map::TrieMap;
+pub use trie_set::TrieSet;
pub use vec::Vec;
+pub use vec_map::VecMap;
mod macros;
-pub mod bitv;
-pub mod btree;
+pub mod binary_heap;
+mod bit;
+mod btree;
pub mod dlist;
pub mod enum_set;
-pub mod priority_queue;
-pub mod ringbuf;
-pub mod smallintmap;
-pub mod treemap;
-pub mod trie;
+pub mod ring_buf;
+mod tree;
+mod trie;
pub mod slice;
pub mod str;
pub mod string;
pub mod vec;
pub mod hash;
+pub mod vec_map;
+
+pub mod bitv {
+ pub use bit::{Bitv, Bits, from_fn, from_bytes};
+}
+
+pub mod bitv_set {
+ pub use bit::{BitvSet, BitPositions, TwoBitPositions};
+}
+
+pub mod tree_map {
+ pub use tree::map::*;
+}
+
+pub mod tree_set {
+ pub use tree::set::*;
+}
+
+pub mod trie_map {
+ pub use trie::map::*;
+}
+
+pub mod trie_set {
+ pub use trie::set::*;
+}
+
+pub mod btree_map {
+ pub use btree::map::*;
+}
+
+pub mod btree_set {
+ pub use btree::set::*;
+}
+
#[cfg(test)] mod bench;
+++ /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.
-
-//! A priority queue implemented with a binary heap.
-//!
-//! Insertions have `O(log n)` time complexity and checking or popping the largest element is
-//! `O(1)`. Converting a vector to a priority queue can be done in-place, and has `O(n)`
-//! complexity. A priority queue can also be converted to a sorted vector in-place, allowing it to
-//! be used for an `O(n log n)` in-place heapsort.
-//!
-//! # Example
-//!
-//! This is a larger example which implements [Dijkstra's algorithm][dijkstra]
-//! to solve the [shortest path problem][sssp] on a [directed graph][dir_graph].
-//! It showcases how to use the `PriorityQueue` with custom types.
-//!
-//! [dijkstra]: http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
-//! [sssp]: http://en.wikipedia.org/wiki/Shortest_path_problem
-//! [dir_graph]: http://en.wikipedia.org/wiki/Directed_graph
-//!
-//! ```
-//! use std::collections::PriorityQueue;
-//! use std::uint;
-//!
-//! #[deriving(Eq, PartialEq)]
-//! struct State {
-//! cost: uint,
-//! position: uint
-//! }
-//!
-//! // The priority queue depends on `Ord`.
-//! // Explicitly implement the trait so the queue becomes a min-heap
-//! // instead of a max-heap.
-//! impl Ord for State {
-//! fn cmp(&self, other: &State) -> Ordering {
-//! // Notice that the we flip the ordering here
-//! other.cost.cmp(&self.cost)
-//! }
-//! }
-//!
-//! // `PartialOrd` needs to be implemented as well.
-//! impl PartialOrd for State {
-//! fn partial_cmp(&self, other: &State) -> Option<Ordering> {
-//! Some(self.cmp(other))
-//! }
-//! }
-//!
-//! // Each node is represented as an `uint`, for a shorter implementation.
-//! struct Edge {
-//! node: uint,
-//! cost: uint
-//! }
-//!
-//! // Dijkstra's shortest path algorithm.
-//!
-//! // Start at `start` and use `dist` to track the current shortest distance
-//! // to each node. This implementation isn't memory efficient as it may leave duplicate
-//! // nodes in the queue. It also uses `uint::MAX` as a sentinel value,
-//! // for a simpler implementation.
-//! fn shortest_path(adj_list: &Vec<Vec<Edge>>, start: uint, goal: uint) -> uint {
-//! // dist[node] = current shortest distance from `start` to `node`
-//! let mut dist = Vec::from_elem(adj_list.len(), uint::MAX);
-//!
-//! let mut pq = PriorityQueue::new();
-//!
-//! // We're at `start`, with a zero cost
-//! dist[start] = 0u;
-//! pq.push(State { cost: 0u, position: start });
-//!
-//! // Examine the frontier with lower cost nodes first (min-heap)
-//! loop {
-//! let State { cost, position } = match pq.pop() {
-//! None => break, // empty
-//! Some(s) => s
-//! };
-//!
-//! // Alternatively we could have continued to find all shortest paths
-//! if position == goal { return cost }
-//!
-//! // Important as we may have already found a better way
-//! if cost > dist[position] { continue }
-//!
-//! // For each node we can reach, see if we can find a way with
-//! // a lower cost going through this node
-//! for edge in adj_list[position].iter() {
-//! let next = State { cost: cost + edge.cost, position: edge.node };
-//!
-//! // If so, add it to the frontier and continue
-//! if next.cost < dist[next.position] {
-//! pq.push(next);
-//! // Relaxation, we have now found a better way
-//! dist[next.position] = next.cost;
-//! }
-//! }
-//! }
-//!
-//! // Goal not reachable
-//! uint::MAX
-//! }
-//!
-//! fn main() {
-//! // This is the directed graph we're going to use.
-//! // The node numbers correspond to the different states,
-//! // and the edge weights symbolises the cost of moving
-//! // from one node to another.
-//! // Note that the edges are one-way.
-//! //
-//! // 7
-//! // +-----------------+
-//! // | |
-//! // v 1 2 |
-//! // 0 -----> 1 -----> 3 ---> 4
-//! // | ^ ^ ^
-//! // | | 1 | |
-//! // | | | 3 | 1
-//! // +------> 2 -------+ |
-//! // 10 | |
-//! // +---------------+
-//! //
-//! // The graph is represented as an adjacency list where each index,
-//! // corresponding to a node value, has a list of outgoing edges.
-//! // Chosen for it's efficiency.
-//! let graph = vec![
-//! // Node 0
-//! vec![Edge { node: 2, cost: 10 },
-//! Edge { node: 1, cost: 1 }],
-//! // Node 1
-//! vec![Edge { node: 3, cost: 2 }],
-//! // Node 2
-//! vec![Edge { node: 1, cost: 1 },
-//! Edge { node: 3, cost: 3 },
-//! Edge { node: 4, cost: 1 }],
-//! // Node 3
-//! vec![Edge { node: 0, cost: 7 },
-//! Edge { node: 4, cost: 2 }],
-//! // Node 4
-//! vec![]];
-//!
-//! assert_eq!(shortest_path(&graph, 0, 1), 1);
-//! assert_eq!(shortest_path(&graph, 0, 3), 3);
-//! assert_eq!(shortest_path(&graph, 3, 0), 7);
-//! assert_eq!(shortest_path(&graph, 0, 4), 5);
-//! assert_eq!(shortest_path(&graph, 4, 0), uint::MAX);
-//! }
-//! ```
-
-#![allow(missing_docs)]
-
-use core::prelude::*;
-
-use core::default::Default;
-use core::mem::{zeroed, replace, swap};
-use core::ptr;
-
-use slice;
-use vec::Vec;
-
-/// A priority queue implemented with a binary heap.
-///
-/// This will be a max-heap.
-#[deriving(Clone)]
-pub struct PriorityQueue<T> {
- data: Vec<T>,
-}
-
-impl<T: Ord> Default for PriorityQueue<T> {
- #[inline]
- fn default() -> PriorityQueue<T> { PriorityQueue::new() }
-}
-
-impl<T: Ord> PriorityQueue<T> {
- /// Creates an empty `PriorityQueue` as a max-heap.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::PriorityQueue;
- /// let pq: PriorityQueue<uint> = PriorityQueue::new();
- /// ```
- pub fn new() -> PriorityQueue<T> { PriorityQueue{data: vec!(),} }
-
- /// Creates an empty `PriorityQueue` with a specific capacity.
- /// This preallocates enough memory for `capacity` elements,
- /// so that the `PriorityQueue` does not have to be reallocated
- /// until it contains at least that many values.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::PriorityQueue;
- /// let pq: PriorityQueue<uint> = PriorityQueue::with_capacity(10u);
- /// ```
- pub fn with_capacity(capacity: uint) -> PriorityQueue<T> {
- PriorityQueue { data: Vec::with_capacity(capacity) }
- }
-
- /// Creates a `PriorityQueue` from a vector. This is sometimes called
- /// `heapifying` the vector.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::PriorityQueue;
- /// let pq = PriorityQueue::from_vec(vec![9i, 1, 2, 7, 3, 2]);
- /// ```
- pub fn from_vec(xs: Vec<T>) -> PriorityQueue<T> {
- let mut q = PriorityQueue{data: xs,};
- let mut n = q.len() / 2;
- while n > 0 {
- n -= 1;
- q.siftdown(n)
- }
- q
- }
-
- /// An iterator visiting all values in underlying vector, in
- /// arbitrary order.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::PriorityQueue;
- /// let pq = PriorityQueue::from_vec(vec![1i, 2, 3, 4]);
- ///
- /// // Print 1, 2, 3, 4 in arbitrary order
- /// for x in pq.iter() {
- /// println!("{}", x);
- /// }
- /// ```
- pub fn iter<'a>(&'a self) -> Items<'a, T> {
- Items { iter: self.data.iter() }
- }
-
- /// Returns the greatest item in a queue, or `None` if it is empty.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::PriorityQueue;
- ///
- /// let mut pq = PriorityQueue::new();
- /// assert_eq!(pq.top(), None);
- ///
- /// pq.push(1i);
- /// pq.push(5i);
- /// pq.push(2i);
- /// assert_eq!(pq.top(), Some(&5i));
- ///
- /// ```
- pub fn top<'a>(&'a self) -> Option<&'a T> {
- if self.is_empty() { None } else { Some(&self.data[0]) }
- }
-
- /// Returns the number of elements the queue can hold without reallocating.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::PriorityQueue;
- ///
- /// let pq: PriorityQueue<uint> = PriorityQueue::with_capacity(100u);
- /// assert!(pq.capacity() >= 100u);
- /// ```
- pub fn capacity(&self) -> uint { self.data.capacity() }
-
- /// Reserves capacity for exactly `n` elements in the `PriorityQueue`.
- /// Do nothing if the capacity is already sufficient.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::PriorityQueue;
- ///
- /// let mut pq: PriorityQueue<uint> = PriorityQueue::new();
- /// pq.reserve_exact(100u);
- /// assert!(pq.capacity() == 100u);
- /// ```
- pub fn reserve_exact(&mut self, n: uint) { self.data.reserve_exact(n) }
-
- /// Reserves capacity for at least `n` elements in the `PriorityQueue`.
- /// Do nothing if the capacity is already sufficient.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::PriorityQueue;
- ///
- /// let mut pq: PriorityQueue<uint> = PriorityQueue::new();
- /// pq.reserve(100u);
- /// assert!(pq.capacity() >= 100u);
- /// ```
- pub fn reserve(&mut self, n: uint) {
- self.data.reserve(n)
- }
-
- /// Removes the greatest item from a queue and returns it, or `None` if it
- /// is empty.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::PriorityQueue;
- ///
- /// let mut pq = PriorityQueue::from_vec(vec![1i, 3]);
- ///
- /// assert_eq!(pq.pop(), Some(3i));
- /// assert_eq!(pq.pop(), Some(1i));
- /// assert_eq!(pq.pop(), None);
- /// ```
- pub fn pop(&mut self) -> Option<T> {
- match self.data.pop() {
- None => { None }
- Some(mut item) => {
- if !self.is_empty() {
- swap(&mut item, &mut self.data[0]);
- self.siftdown(0);
- }
- Some(item)
- }
- }
- }
-
- /// Pushes an item onto the queue.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::PriorityQueue;
- ///
- /// let mut pq = PriorityQueue::new();
- /// pq.push(3i);
- /// pq.push(5i);
- /// pq.push(1i);
- ///
- /// assert_eq!(pq.len(), 3);
- /// assert_eq!(pq.top(), Some(&5i));
- /// ```
- pub fn push(&mut self, item: T) {
- self.data.push(item);
- let new_len = self.len() - 1;
- self.siftup(0, new_len);
- }
-
- /// Pushes an item onto a queue then pops the greatest item off the queue in
- /// an optimized fashion.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::PriorityQueue;
- ///
- /// let mut pq = PriorityQueue::new();
- /// pq.push(1i);
- /// pq.push(5i);
- ///
- /// assert_eq!(pq.push_pop(3i), 5);
- /// assert_eq!(pq.push_pop(9i), 9);
- /// assert_eq!(pq.len(), 2);
- /// assert_eq!(pq.top(), Some(&3i));
- /// ```
- pub fn push_pop(&mut self, mut item: T) -> T {
- if !self.is_empty() && *self.top().unwrap() > item {
- swap(&mut item, &mut self.data[0]);
- self.siftdown(0);
- }
- item
- }
-
- /// Pops the greatest item off a queue then pushes an item onto the queue in
- /// an optimized fashion. The push is done regardless of whether the queue
- /// was empty.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::PriorityQueue;
- ///
- /// let mut pq = PriorityQueue::new();
- ///
- /// assert_eq!(pq.replace(1i), None);
- /// assert_eq!(pq.replace(3i), Some(1i));
- /// assert_eq!(pq.len(), 1);
- /// assert_eq!(pq.top(), Some(&3i));
- /// ```
- pub fn replace(&mut self, mut item: T) -> Option<T> {
- if !self.is_empty() {
- swap(&mut item, &mut self.data[0]);
- self.siftdown(0);
- Some(item)
- } else {
- self.push(item);
- None
- }
- }
-
- /// Consumes the `PriorityQueue` and returns the underlying vector
- /// in arbitrary order.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::PriorityQueue;
- ///
- /// let pq = PriorityQueue::from_vec(vec![1i, 2, 3, 4, 5, 6, 7]);
- /// let vec = pq.into_vec();
- ///
- /// // Will print in some order
- /// for x in vec.iter() {
- /// println!("{}", x);
- /// }
- /// ```
- pub fn into_vec(self) -> Vec<T> { let PriorityQueue{data: v} = self; v }
-
- /// Consumes the `PriorityQueue` and returns a vector in sorted
- /// (ascending) order.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::PriorityQueue;
- ///
- /// let mut pq = PriorityQueue::from_vec(vec![1i, 2, 4, 5, 7]);
- /// pq.push(6);
- /// pq.push(3);
- ///
- /// let vec = pq.into_sorted_vec();
- /// assert_eq!(vec, vec![1i, 2, 3, 4, 5, 6, 7]);
- /// ```
- pub fn into_sorted_vec(self) -> Vec<T> {
- let mut q = self;
- let mut end = q.len();
- while end > 1 {
- end -= 1;
- q.data.as_mut_slice().swap(0, end);
- q.siftdown_range(0, end)
- }
- q.into_vec()
- }
-
- // The implementations of siftup and siftdown use unsafe blocks in
- // order to move an element out of the vector (leaving behind a
- // zeroed element), shift along the others and move it back into the
- // vector over the junk element. This reduces the constant factor
- // compared to using swaps, which involves twice as many moves.
- fn siftup(&mut self, start: uint, mut pos: uint) {
- unsafe {
- let new = replace(&mut self.data[pos], zeroed());
-
- while pos > start {
- let parent = (pos - 1) >> 1;
- if new > self.data[parent] {
- let x = replace(&mut self.data[parent], zeroed());
- ptr::write(&mut self.data[pos], x);
- pos = parent;
- continue
- }
- break
- }
- ptr::write(&mut self.data[pos], new);
- }
- }
-
- fn siftdown_range(&mut self, mut pos: uint, end: uint) {
- unsafe {
- let start = pos;
- let new = replace(&mut self.data[pos], zeroed());
-
- let mut child = 2 * pos + 1;
- while child < end {
- let right = child + 1;
- if right < end && !(self.data[child] > self.data[right]) {
- child = right;
- }
- let x = replace(&mut self.data[child], zeroed());
- ptr::write(&mut self.data[pos], x);
- pos = child;
- child = 2 * pos + 1;
- }
-
- ptr::write(&mut self.data[pos], new);
- self.siftup(start, pos);
- }
- }
-
- fn siftdown(&mut self, pos: uint) {
- let len = self.len();
- self.siftdown_range(pos, len);
- }
-
- /// Returns the length of the queue.
- pub fn len(&self) -> uint { self.data.len() }
-
- /// Returns true if the queue contains no elements
- pub fn is_empty(&self) -> bool { self.len() == 0 }
-
- /// Drops all items from the queue.
- pub fn clear(&mut self) { self.data.truncate(0) }
-}
-
-/// `PriorityQueue` iterator.
-pub struct Items <'a, T:'a> {
- iter: slice::Items<'a, T>,
-}
-
-impl<'a, T> Iterator<&'a T> for Items<'a, T> {
- #[inline]
- fn next(&mut self) -> Option<(&'a T)> { self.iter.next() }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
-}
-
-impl<T: Ord> FromIterator<T> for PriorityQueue<T> {
- fn from_iter<Iter: Iterator<T>>(mut iter: Iter) -> PriorityQueue<T> {
- let vec: Vec<T> = iter.collect();
- PriorityQueue::from_vec(vec)
- }
-}
-
-impl<T: Ord> Extendable<T> for PriorityQueue<T> {
- fn extend<Iter: Iterator<T>>(&mut self, mut iter: Iter) {
- let (lower, _) = iter.size_hint();
-
- let len = self.capacity();
- self.reserve(len + lower);
-
- for elem in iter {
- self.push(elem);
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use std::prelude::*;
-
- use priority_queue::PriorityQueue;
- use vec::Vec;
-
- #[test]
- fn test_iterator() {
- let data = vec!(5i, 9, 3);
- let iterout = [9i, 5, 3];
- let pq = PriorityQueue::from_vec(data);
- let mut i = 0;
- for el in pq.iter() {
- assert_eq!(*el, iterout[i]);
- i += 1;
- }
- }
-
- #[test]
- fn test_top_and_pop() {
- let data = vec!(2u, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1);
- let mut sorted = data.clone();
- sorted.sort();
- let mut heap = PriorityQueue::from_vec(data);
- while !heap.is_empty() {
- assert_eq!(heap.top().unwrap(), sorted.last().unwrap());
- assert_eq!(heap.pop().unwrap(), sorted.pop().unwrap());
- }
- }
-
- #[test]
- fn test_push() {
- let mut heap = PriorityQueue::from_vec(vec!(2i, 4, 9));
- assert_eq!(heap.len(), 3);
- assert!(*heap.top().unwrap() == 9);
- heap.push(11);
- assert_eq!(heap.len(), 4);
- assert!(*heap.top().unwrap() == 11);
- heap.push(5);
- assert_eq!(heap.len(), 5);
- assert!(*heap.top().unwrap() == 11);
- heap.push(27);
- assert_eq!(heap.len(), 6);
- assert!(*heap.top().unwrap() == 27);
- heap.push(3);
- assert_eq!(heap.len(), 7);
- assert!(*heap.top().unwrap() == 27);
- heap.push(103);
- assert_eq!(heap.len(), 8);
- assert!(*heap.top().unwrap() == 103);
- }
-
- #[test]
- fn test_push_unique() {
- let mut heap = PriorityQueue::from_vec(vec!(box 2i, box 4, box 9));
- assert_eq!(heap.len(), 3);
- assert!(*heap.top().unwrap() == box 9);
- heap.push(box 11);
- assert_eq!(heap.len(), 4);
- assert!(*heap.top().unwrap() == box 11);
- heap.push(box 5);
- assert_eq!(heap.len(), 5);
- assert!(*heap.top().unwrap() == box 11);
- heap.push(box 27);
- assert_eq!(heap.len(), 6);
- assert!(*heap.top().unwrap() == box 27);
- heap.push(box 3);
- assert_eq!(heap.len(), 7);
- assert!(*heap.top().unwrap() == box 27);
- heap.push(box 103);
- assert_eq!(heap.len(), 8);
- assert!(*heap.top().unwrap() == box 103);
- }
-
- #[test]
- fn test_push_pop() {
- let mut heap = PriorityQueue::from_vec(vec!(5i, 5, 2, 1, 3));
- assert_eq!(heap.len(), 5);
- assert_eq!(heap.push_pop(6), 6);
- assert_eq!(heap.len(), 5);
- assert_eq!(heap.push_pop(0), 5);
- assert_eq!(heap.len(), 5);
- assert_eq!(heap.push_pop(4), 5);
- assert_eq!(heap.len(), 5);
- assert_eq!(heap.push_pop(1), 4);
- assert_eq!(heap.len(), 5);
- }
-
- #[test]
- fn test_replace() {
- let mut heap = PriorityQueue::from_vec(vec!(5i, 5, 2, 1, 3));
- assert_eq!(heap.len(), 5);
- assert_eq!(heap.replace(6).unwrap(), 5);
- assert_eq!(heap.len(), 5);
- assert_eq!(heap.replace(0).unwrap(), 6);
- assert_eq!(heap.len(), 5);
- assert_eq!(heap.replace(4).unwrap(), 5);
- assert_eq!(heap.len(), 5);
- assert_eq!(heap.replace(1).unwrap(), 4);
- assert_eq!(heap.len(), 5);
- }
-
- fn check_to_vec(mut data: Vec<int>) {
- let heap = PriorityQueue::from_vec(data.clone());
- let mut v = heap.clone().into_vec();
- v.sort();
- data.sort();
-
- assert_eq!(v.as_slice(), data.as_slice());
- assert_eq!(heap.into_sorted_vec().as_slice(), data.as_slice());
- }
-
- #[test]
- fn test_to_vec() {
- check_to_vec(vec!());
- check_to_vec(vec!(5i));
- check_to_vec(vec!(3i, 2));
- check_to_vec(vec!(2i, 3));
- check_to_vec(vec!(5i, 1, 2));
- check_to_vec(vec!(1i, 100, 2, 3));
- check_to_vec(vec!(1i, 3, 5, 7, 9, 2, 4, 6, 8, 0));
- check_to_vec(vec!(2i, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1));
- check_to_vec(vec!(9i, 11, 9, 9, 9, 9, 11, 2, 3, 4, 11, 9, 0, 0, 0, 0));
- check_to_vec(vec!(0i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
- check_to_vec(vec!(10i, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0));
- check_to_vec(vec!(0i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 1, 2));
- check_to_vec(vec!(5i, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1));
- }
-
- #[test]
- fn test_empty_pop() {
- let mut heap: PriorityQueue<int> = PriorityQueue::new();
- assert!(heap.pop().is_none());
- }
-
- #[test]
- fn test_empty_top() {
- let empty: PriorityQueue<int> = PriorityQueue::new();
- assert!(empty.top().is_none());
- }
-
- #[test]
- fn test_empty_replace() {
- let mut heap: PriorityQueue<int> = PriorityQueue::new();
- heap.replace(5).is_none();
- }
-
- #[test]
- fn test_from_iter() {
- let xs = vec!(9u, 8, 7, 6, 5, 4, 3, 2, 1);
-
- let mut q: PriorityQueue<uint> = xs.as_slice().iter().rev().map(|&x| x).collect();
-
- for &x in xs.iter() {
- assert_eq!(q.pop().unwrap(), x);
- }
- }
-}
--- /dev/null
+// Copyright 2012-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.
+
+//! This crate implements a double-ended queue with `O(1)` amortized inserts and removals from both
+//! ends of the container. It also has `O(1)` indexing like a vector. The contained elements are
+//! not required to be copyable, and the queue will be sendable if the contained type is sendable.
+//! Its interface `Deque` is defined in `collections`.
+
+use core::prelude::*;
+
+use core::cmp;
+use core::default::Default;
+use core::fmt;
+use core::iter;
+use core::slice;
+use std::hash::{Writer, Hash};
+
+use vec::Vec;
+
+static INITIAL_CAPACITY: uint = 8u; // 2^3
+static MINIMUM_CAPACITY: uint = 2u;
+
+/// `RingBuf` is a circular buffer that implements `Deque`.
+#[deriving(Clone)]
+pub struct RingBuf<T> {
+ nelts: uint,
+ lo: uint,
+ elts: Vec<Option<T>>
+}
+
+impl<T> Default for RingBuf<T> {
+ #[inline]
+ fn default() -> RingBuf<T> { RingBuf::new() }
+}
+
+impl<T> RingBuf<T> {
+ /// Creates an empty `RingBuf`.
+ pub fn new() -> RingBuf<T> {
+ RingBuf::with_capacity(INITIAL_CAPACITY)
+ }
+
+ /// Creates an empty `RingBuf` with space for at least `n` elements.
+ pub fn with_capacity(n: uint) -> RingBuf<T> {
+ RingBuf{nelts: 0, lo: 0,
+ elts: Vec::from_fn(cmp::max(MINIMUM_CAPACITY, n), |_| None)}
+ }
+
+ /// Retrieves an element in the `RingBuf` by index.
+ ///
+ /// Fails if there is no element with the given index.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// # #![allow(deprecated)]
+ /// use std::collections::RingBuf;
+ ///
+ /// let mut buf = RingBuf::new();
+ /// buf.push(3i);
+ /// buf.push(4);
+ /// buf.push(5);
+ /// *buf.get_mut(1) = 7;
+ /// assert_eq!(buf[1], 7);
+ /// ```
+ #[deprecated = "use indexing instead: `buf[index] = value`"]
+ pub fn get_mut(&mut self, i: uint) -> &mut T {
+ &mut self[i]
+ }
+
+ /// Swaps elements at indices `i` and `j`.
+ ///
+ /// `i` and `j` may be equal.
+ ///
+ /// Fails if there is no element with either index.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use std::collections::RingBuf;
+ ///
+ /// let mut buf = RingBuf::new();
+ /// buf.push(3i);
+ /// buf.push(4);
+ /// buf.push(5);
+ /// buf.swap(0, 2);
+ /// assert_eq!(buf[0], 5);
+ /// assert_eq!(buf[2], 3);
+ /// ```
+ pub fn swap(&mut self, i: uint, j: uint) {
+ assert!(i < self.len());
+ assert!(j < self.len());
+ let ri = self.raw_index(i);
+ let rj = self.raw_index(j);
+ self.elts.as_mut_slice().swap(ri, rj);
+ }
+
+ /// Returns the index in the underlying `Vec` for a given logical element
+ /// index.
+ fn raw_index(&self, idx: uint) -> uint {
+ raw_index(self.lo, self.elts.len(), idx)
+ }
+
+ /// Reserves capacity for exactly `n` elements in the given `RingBuf`,
+ /// doing nothing if `self`'s capacity is already equal to or greater
+ /// than the requested capacity.
+ pub fn reserve_exact(&mut self, n: uint) {
+ self.elts.reserve_exact(n);
+ }
+
+ /// Reserves capacity for at least `n` elements in the given `RingBuf`,
+ /// over-allocating in case the caller needs to reserve additional
+ /// space.
+ ///
+ /// Do nothing if `self`'s capacity is already equal to or greater
+ /// than the requested capacity.
+ pub fn reserve(&mut self, n: uint) {
+ self.elts.reserve(n);
+ }
+
+ /// Returns a front-to-back iterator.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use std::collections::RingBuf;
+ ///
+ /// let mut buf = RingBuf::new();
+ /// buf.push(5i);
+ /// buf.push(3);
+ /// buf.push(4);
+ /// let b: &[_] = &[&5, &3, &4];
+ /// assert_eq!(buf.iter().collect::<Vec<&int>>().as_slice(), b);
+ /// ```
+ pub fn iter(&self) -> Items<T> {
+ Items{index: 0, rindex: self.nelts, lo: self.lo, elts: self.elts.as_slice()}
+ }
+
+ /// Returns a front-to-back iterator which returns mutable references.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use std::collections::RingBuf;
+ ///
+ /// let mut buf = RingBuf::new();
+ /// buf.push(5i);
+ /// buf.push(3);
+ /// buf.push(4);
+ /// for num in buf.iter_mut() {
+ /// *num = *num - 2;
+ /// }
+ /// let b: &[_] = &[&mut 3, &mut 1, &mut 2];
+ /// assert_eq!(buf.iter_mut().collect::<Vec<&mut int>>()[], b);
+ /// ```
+ pub fn iter_mut(&mut self) -> MutItems<T> {
+ let start_index = raw_index(self.lo, self.elts.len(), 0);
+ let end_index = raw_index(self.lo, self.elts.len(), self.nelts);
+
+ // Divide up the array
+ if end_index <= start_index {
+ // Items to iterate goes from:
+ // start_index to self.elts.len()
+ // and then
+ // 0 to end_index
+ let (temp, remaining1) = self.elts.split_at_mut(start_index);
+ let (remaining2, _) = temp.split_at_mut(end_index);
+ MutItems {
+ remaining1: remaining1.iter_mut(),
+ remaining2: remaining2.iter_mut(),
+ nelts: self.nelts,
+ }
+ } else {
+ // Items to iterate goes from start_index to end_index:
+ let (empty, elts) = self.elts.split_at_mut(0);
+ let remaining1 = elts[mut start_index..end_index];
+ MutItems {
+ remaining1: remaining1.iter_mut(),
+ remaining2: empty.iter_mut(),
+ nelts: self.nelts,
+ }
+ }
+ }
+
+ /// Returns the number of elements in the `RingBuf`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::RingBuf;
+ ///
+ /// let mut v = RingBuf::new();
+ /// assert_eq!(v.len(), 0);
+ /// v.push(1i);
+ /// assert_eq!(v.len(), 1);
+ /// ```
+ pub fn len(&self) -> uint { self.nelts }
+
+ /// Returns true if the buffer contains no elements
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::RingBuf;
+ ///
+ /// let mut v = RingBuf::new();
+ /// assert!(v.is_empty());
+ /// v.push_front(1i);
+ /// assert!(!v.is_empty());
+ /// ```
+ pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+ /// Clears the buffer, removing all values.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::RingBuf;
+ ///
+ /// let mut v = RingBuf::new();
+ /// v.push(1i);
+ /// v.clear();
+ /// assert!(v.is_empty());
+ /// ```
+ pub fn clear(&mut self) {
+ for x in self.elts.iter_mut() { *x = None }
+ self.nelts = 0;
+ self.lo = 0;
+ }
+
+ /// Provides a reference to the front element, or `None` if the sequence is
+ /// empty.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::RingBuf;
+ ///
+ /// let mut d = RingBuf::new();
+ /// assert_eq!(d.front(), None);
+ ///
+ /// d.push(1i);
+ /// d.push(2i);
+ /// assert_eq!(d.front(), Some(&1i));
+ /// ```
+ pub fn front(&self) -> Option<&T> {
+ if self.nelts > 0 { Some(&self[0]) } else { None }
+ }
+
+ /// Provides a mutable reference to the front element, or `None` if the
+ /// sequence is empty.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::RingBuf;
+ ///
+ /// let mut d = RingBuf::new();
+ /// assert_eq!(d.front_mut(), None);
+ ///
+ /// d.push(1i);
+ /// d.push(2i);
+ /// match d.front_mut() {
+ /// Some(x) => *x = 9i,
+ /// None => (),
+ /// }
+ /// assert_eq!(d.front(), Some(&9i));
+ /// ```
+ pub fn front_mut(&mut self) -> Option<&mut T> {
+ if self.nelts > 0 { Some(&mut self[0]) } else { None }
+ }
+
+ /// Provides a reference to the back element, or `None` if the sequence is
+ /// empty.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::RingBuf;
+ ///
+ /// let mut d = RingBuf::new();
+ /// assert_eq!(d.back(), None);
+ ///
+ /// d.push(1i);
+ /// d.push(2i);
+ /// assert_eq!(d.back(), Some(&2i));
+ /// ```
+ pub fn back(&self) -> Option<&T> {
+ if self.nelts > 0 { Some(&self[self.nelts - 1]) } else { None }
+ }
+
+ /// Provides a mutable reference to the back element, or `None` if the
+ /// sequence is empty.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::RingBuf;
+ ///
+ /// let mut d = RingBuf::new();
+ /// assert_eq!(d.back(), None);
+ ///
+ /// d.push(1i);
+ /// d.push(2i);
+ /// match d.back_mut() {
+ /// Some(x) => *x = 9i,
+ /// None => (),
+ /// }
+ /// assert_eq!(d.back(), Some(&9i));
+ /// ```
+ pub fn back_mut(&mut self) -> Option<&mut T> {
+ let nelts = self.nelts;
+ if nelts > 0 { Some(&mut self[nelts - 1]) } else { None }
+ }
+
+ /// Removes the first element and returns it, or `None` if the sequence is
+ /// empty.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::RingBuf;
+ ///
+ /// let mut d = RingBuf::new();
+ /// d.push(1i);
+ /// d.push(2i);
+ ///
+ /// assert_eq!(d.pop_front(), Some(1i));
+ /// assert_eq!(d.pop_front(), Some(2i));
+ /// assert_eq!(d.pop_front(), None);
+ /// ```
+ pub fn pop_front(&mut self) -> Option<T> {
+ let result = self.elts[self.lo].take();
+ if result.is_some() {
+ self.lo = (self.lo + 1u) % self.elts.len();
+ self.nelts -= 1u;
+ }
+ result
+ }
+
+ /// Inserts an element first in the sequence.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::RingBuf;
+ ///
+ /// let mut d = RingBuf::new();
+ /// d.push_front(1i);
+ /// d.push_front(2i);
+ /// assert_eq!(d.front(), Some(&2i));
+ /// ```
+ pub fn push_front(&mut self, t: T) {
+ if self.nelts == self.elts.len() {
+ grow(self.nelts, &mut self.lo, &mut self.elts);
+ }
+ if self.lo == 0u {
+ self.lo = self.elts.len() - 1u;
+ } else { self.lo -= 1u; }
+ self.elts[self.lo] = Some(t);
+ self.nelts += 1u;
+ }
+
+ /// Appends an element to the back of a buffer
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use std::collections::RingBuf;
+ ///
+ /// let mut buf = RingBuf::new();
+ /// buf.push(1i);
+ /// buf.push(3);
+ /// assert_eq!(3, *buf.back().unwrap());
+ /// ```
+ pub fn push(&mut self, t: T) {
+ if self.nelts == self.elts.len() {
+ grow(self.nelts, &mut self.lo, &mut self.elts);
+ }
+ let hi = self.raw_index(self.nelts);
+ self.elts[hi] = Some(t);
+ self.nelts += 1u;
+ }
+
+ /// Removes the last element from a buffer and returns it, or `None` if
+ /// it is empty.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use std::collections::RingBuf;
+ ///
+ /// let mut buf = RingBuf::new();
+ /// assert_eq!(buf.pop(), None);
+ /// buf.push(1i);
+ /// buf.push(3);
+ /// assert_eq!(buf.pop(), Some(3));
+ /// ```
+ pub fn pop(&mut self) -> Option<T> {
+ if self.nelts > 0 {
+ self.nelts -= 1;
+ let hi = self.raw_index(self.nelts);
+ self.elts[hi].take()
+ } else {
+ None
+ }
+ }
+}
+
+/// `RingBuf` iterator.
+pub struct Items<'a, T:'a> {
+ lo: uint,
+ index: uint,
+ rindex: uint,
+ elts: &'a [Option<T>],
+}
+
+impl<'a, T> Iterator<&'a T> for Items<'a, T> {
+ #[inline]
+ fn next(&mut self) -> Option<&'a T> {
+ if self.index == self.rindex {
+ return None;
+ }
+ let raw_index = raw_index(self.lo, self.elts.len(), self.index);
+ self.index += 1;
+ Some(self.elts[raw_index].as_ref().unwrap())
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ let len = self.rindex - self.index;
+ (len, Some(len))
+ }
+}
+
+impl<'a, T> DoubleEndedIterator<&'a T> for Items<'a, T> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a T> {
+ if self.index == self.rindex {
+ return None;
+ }
+ self.rindex -= 1;
+ let raw_index = raw_index(self.lo, self.elts.len(), self.rindex);
+ Some(self.elts[raw_index].as_ref().unwrap())
+ }
+}
+
+impl<'a, T> ExactSize<&'a T> for Items<'a, T> {}
+
+impl<'a, T> RandomAccessIterator<&'a T> for Items<'a, T> {
+ #[inline]
+ fn indexable(&self) -> uint { self.rindex - self.index }
+
+ #[inline]
+ fn idx(&mut self, j: uint) -> Option<&'a T> {
+ if j >= self.indexable() {
+ None
+ } else {
+ let raw_index = raw_index(self.lo, self.elts.len(), self.index + j);
+ Some(self.elts[raw_index].as_ref().unwrap())
+ }
+ }
+}
+
+/// `RingBuf` mutable iterator.
+pub struct MutItems<'a, T:'a> {
+ remaining1: slice::MutItems<'a, Option<T>>,
+ remaining2: slice::MutItems<'a, Option<T>>,
+ nelts: uint,
+}
+
+impl<'a, T> Iterator<&'a mut T> for MutItems<'a, T> {
+ #[inline]
+ fn next(&mut self) -> Option<&'a mut T> {
+ if self.nelts == 0 {
+ return None;
+ }
+ self.nelts -= 1;
+ match self.remaining1.next() {
+ Some(ptr) => return Some(ptr.as_mut().unwrap()),
+ None => {}
+ }
+ match self.remaining2.next() {
+ Some(ptr) => return Some(ptr.as_mut().unwrap()),
+ None => unreachable!(),
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ (self.nelts, Some(self.nelts))
+ }
+}
+
+impl<'a, T> DoubleEndedIterator<&'a mut T> for MutItems<'a, T> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a mut T> {
+ if self.nelts == 0 {
+ return None;
+ }
+ self.nelts -= 1;
+ match self.remaining2.next_back() {
+ Some(ptr) => return Some(ptr.as_mut().unwrap()),
+ None => {}
+ }
+ match self.remaining1.next_back() {
+ Some(ptr) => return Some(ptr.as_mut().unwrap()),
+ None => unreachable!(),
+ }
+ }
+}
+
+impl<'a, T> ExactSize<&'a mut T> for MutItems<'a, T> {}
+
+/// Grow is only called on full elts, so nelts is also len(elts), unlike
+/// elsewhere.
+fn grow<T>(nelts: uint, loptr: &mut uint, elts: &mut Vec<Option<T>>) {
+ assert_eq!(nelts, elts.len());
+ let lo = *loptr;
+ elts.reserve(nelts * 2);
+ let newlen = elts.capacity();
+
+ /* fill with None */
+ for _ in range(elts.len(), newlen) {
+ elts.push(None);
+ }
+
+ /*
+ Move the shortest half into the newly reserved area.
+ lo ---->|
+ nelts ----------->|
+ [o o o|o o o o o]
+ A [. . .|o o o o o o o o|. . . . .]
+ B [o o o|. . . . . . . .|o o o o o]
+ */
+
+ assert!(newlen - nelts/2 >= nelts);
+ if lo <= (nelts - lo) { // A
+ for i in range(0u, lo) {
+ elts.as_mut_slice().swap(i, nelts + i);
+ }
+ } else { // B
+ for i in range(lo, nelts) {
+ elts.as_mut_slice().swap(i, newlen - nelts + i);
+ }
+ *loptr += newlen - nelts;
+ }
+}
+
+/// Returns the index in the underlying `Vec` for a given logical element index.
+fn raw_index(lo: uint, len: uint, index: uint) -> uint {
+ if lo >= len - index {
+ lo + index - len
+ } else {
+ lo + index
+ }
+}
+
+impl<A: PartialEq> PartialEq for RingBuf<A> {
+ fn eq(&self, other: &RingBuf<A>) -> bool {
+ self.nelts == other.nelts &&
+ self.iter().zip(other.iter()).all(|(a, b)| a.eq(b))
+ }
+ fn ne(&self, other: &RingBuf<A>) -> bool {
+ !self.eq(other)
+ }
+}
+
+impl<A: Eq> Eq for RingBuf<A> {}
+
+impl<A: PartialOrd> PartialOrd for RingBuf<A> {
+ fn partial_cmp(&self, other: &RingBuf<A>) -> Option<Ordering> {
+ iter::order::partial_cmp(self.iter(), other.iter())
+ }
+}
+
+impl<A: Ord> Ord for RingBuf<A> {
+ #[inline]
+ fn cmp(&self, other: &RingBuf<A>) -> Ordering {
+ iter::order::cmp(self.iter(), other.iter())
+ }
+}
+
+impl<S: Writer, A: Hash<S>> Hash<S> for RingBuf<A> {
+ fn hash(&self, state: &mut S) {
+ self.len().hash(state);
+ for elt in self.iter() {
+ elt.hash(state);
+ }
+ }
+}
+
+impl<A> Index<uint, A> for RingBuf<A> {
+ #[inline]
+ fn index<'a>(&'a self, i: &uint) -> &'a A {
+ let idx = self.raw_index(*i);
+ match self.elts[idx] {
+ None => panic!(),
+ Some(ref v) => v,
+ }
+ }
+}
+
+impl<A> IndexMut<uint, A> for RingBuf<A> {
+ #[inline]
+ fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut A {
+ let idx = self.raw_index(*i);
+ match *(&mut self.elts[idx]) {
+ None => panic!(),
+ Some(ref mut v) => v
+ }
+ }
+}
+
+impl<A> FromIterator<A> for RingBuf<A> {
+ fn from_iter<T: Iterator<A>>(iterator: T) -> RingBuf<A> {
+ let (lower, _) = iterator.size_hint();
+ let mut deq = RingBuf::with_capacity(lower);
+ deq.extend(iterator);
+ deq
+ }
+}
+
+impl<A> Extendable<A> for RingBuf<A> {
+ fn extend<T: Iterator<A>>(&mut self, mut iterator: T) {
+ for elt in iterator {
+ self.push(elt);
+ }
+ }
+}
+
+impl<T: fmt::Show> fmt::Show for RingBuf<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ try!(write!(f, "["));
+
+ for (i, e) in self.iter().enumerate() {
+ if i != 0 { try!(write!(f, ", ")); }
+ try!(write!(f, "{}", *e));
+ }
+
+ write!(f, "]")
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use std::fmt::Show;
+ use std::prelude::*;
+ use std::hash;
+ use test::Bencher;
+ use test;
+
+ use super::RingBuf;
+ use vec::Vec;
+
+ #[test]
+ #[allow(deprecated)]
+ fn test_simple() {
+ let mut d = RingBuf::new();
+ assert_eq!(d.len(), 0u);
+ d.push_front(17i);
+ d.push_front(42i);
+ d.push(137);
+ assert_eq!(d.len(), 3u);
+ d.push(137);
+ assert_eq!(d.len(), 4u);
+ debug!("{}", d.front());
+ assert_eq!(*d.front().unwrap(), 42);
+ debug!("{}", d.back());
+ assert_eq!(*d.back().unwrap(), 137);
+ let mut i = d.pop_front();
+ debug!("{}", i);
+ assert_eq!(i, Some(42));
+ i = d.pop();
+ debug!("{}", i);
+ assert_eq!(i, Some(137));
+ i = d.pop();
+ debug!("{}", i);
+ assert_eq!(i, Some(137));
+ i = d.pop();
+ debug!("{}", i);
+ assert_eq!(i, Some(17));
+ assert_eq!(d.len(), 0u);
+ d.push(3);
+ assert_eq!(d.len(), 1u);
+ d.push_front(2);
+ assert_eq!(d.len(), 2u);
+ d.push(4);
+ assert_eq!(d.len(), 3u);
+ d.push_front(1);
+ assert_eq!(d.len(), 4u);
+ debug!("{}", d[0]);
+ debug!("{}", d[1]);
+ debug!("{}", d[2]);
+ debug!("{}", d[3]);
+ assert_eq!(d[0], 1);
+ assert_eq!(d[1], 2);
+ assert_eq!(d[2], 3);
+ assert_eq!(d[3], 4);
+ }
+
+ #[cfg(test)]
+ fn test_parameterized<T:Clone + PartialEq + Show>(a: T, b: T, c: T, d: T) {
+ let mut deq = RingBuf::new();
+ assert_eq!(deq.len(), 0);
+ deq.push_front(a.clone());
+ deq.push_front(b.clone());
+ deq.push(c.clone());
+ assert_eq!(deq.len(), 3);
+ deq.push(d.clone());
+ assert_eq!(deq.len(), 4);
+ assert_eq!((*deq.front().unwrap()).clone(), b.clone());
+ assert_eq!((*deq.back().unwrap()).clone(), d.clone());
+ assert_eq!(deq.pop_front().unwrap(), b.clone());
+ assert_eq!(deq.pop().unwrap(), d.clone());
+ assert_eq!(deq.pop().unwrap(), c.clone());
+ assert_eq!(deq.pop().unwrap(), a.clone());
+ assert_eq!(deq.len(), 0);
+ deq.push(c.clone());
+ assert_eq!(deq.len(), 1);
+ deq.push_front(b.clone());
+ assert_eq!(deq.len(), 2);
+ deq.push(d.clone());
+ assert_eq!(deq.len(), 3);
+ deq.push_front(a.clone());
+ assert_eq!(deq.len(), 4);
+ assert_eq!(deq[0].clone(), a.clone());
+ assert_eq!(deq[1].clone(), b.clone());
+ assert_eq!(deq[2].clone(), c.clone());
+ assert_eq!(deq[3].clone(), d.clone());
+ }
+
+ #[test]
+ fn test_push_front_grow() {
+ let mut deq = RingBuf::new();
+ for i in range(0u, 66) {
+ deq.push_front(i);
+ }
+ assert_eq!(deq.len(), 66);
+
+ for i in range(0u, 66) {
+ assert_eq!(deq[i], 65 - i);
+ }
+
+ let mut deq = RingBuf::new();
+ for i in range(0u, 66) {
+ deq.push(i);
+ }
+
+ for i in range(0u, 66) {
+ assert_eq!(deq[i], i);
+ }
+ }
+
+ #[test]
+ fn test_index() {
+ let mut deq = RingBuf::new();
+ for i in range(1u, 4) {
+ deq.push_front(i);
+ }
+ assert_eq!(deq[1], 2);
+ }
+
+ #[test]
+ #[should_fail]
+ fn test_index_out_of_bounds() {
+ let mut deq = RingBuf::new();
+ for i in range(1u, 4) {
+ deq.push_front(i);
+ }
+ deq[3];
+ }
+
+ #[bench]
+ fn bench_new(b: &mut test::Bencher) {
+ b.iter(|| {
+ let _: RingBuf<u64> = RingBuf::new();
+ })
+ }
+
+ #[bench]
+ fn bench_push_back(b: &mut test::Bencher) {
+ let mut deq = RingBuf::new();
+ b.iter(|| {
+ deq.push(0i);
+ })
+ }
+
+ #[bench]
+ fn bench_push_front(b: &mut test::Bencher) {
+ let mut deq = RingBuf::new();
+ b.iter(|| {
+ deq.push_front(0i);
+ })
+ }
+
+ #[bench]
+ fn bench_grow(b: &mut test::Bencher) {
+ let mut deq = RingBuf::new();
+ b.iter(|| {
+ for _ in range(0i, 65) {
+ deq.push_front(1i);
+ }
+ })
+ }
+
+ #[deriving(Clone, PartialEq, Show)]
+ enum Taggy {
+ One(int),
+ Two(int, int),
+ Three(int, int, int),
+ }
+
+ #[deriving(Clone, PartialEq, Show)]
+ enum Taggypar<T> {
+ Onepar(int),
+ Twopar(int, int),
+ Threepar(int, int, int),
+ }
+
+ #[deriving(Clone, PartialEq, Show)]
+ struct RecCy {
+ x: int,
+ y: int,
+ t: Taggy
+ }
+
+ #[test]
+ fn test_param_int() {
+ test_parameterized::<int>(5, 72, 64, 175);
+ }
+
+ #[test]
+ fn test_param_taggy() {
+ test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3), Two(17, 42));
+ }
+
+ #[test]
+ fn test_param_taggypar() {
+ test_parameterized::<Taggypar<int>>(Onepar::<int>(1),
+ Twopar::<int>(1, 2),
+ Threepar::<int>(1, 2, 3),
+ Twopar::<int>(17, 42));
+ }
+
+ #[test]
+ fn test_param_reccy() {
+ let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
+ let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
+ let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
+ let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
+ test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
+ }
+
+ #[test]
+ fn test_with_capacity() {
+ let mut d = RingBuf::with_capacity(0);
+ d.push(1i);
+ assert_eq!(d.len(), 1);
+ let mut d = RingBuf::with_capacity(50);
+ d.push(1i);
+ assert_eq!(d.len(), 1);
+ }
+
+ #[test]
+ fn test_with_capacity_non_power_two() {
+ let mut d3 = RingBuf::with_capacity(3);
+ d3.push(1i);
+
+ // X = None, | = lo
+ // [|1, X, X]
+ assert_eq!(d3.pop_front(), Some(1));
+ // [X, |X, X]
+ assert_eq!(d3.front(), None);
+
+ // [X, |3, X]
+ d3.push(3);
+ // [X, |3, 6]
+ d3.push(6);
+ // [X, X, |6]
+ assert_eq!(d3.pop_front(), Some(3));
+
+ // Pushing the lo past half way point to trigger
+ // the 'B' scenario for growth
+ // [9, X, |6]
+ d3.push(9);
+ // [9, 12, |6]
+ d3.push(12);
+
+ d3.push(15);
+ // There used to be a bug here about how the
+ // RingBuf made growth assumptions about the
+ // underlying Vec which didn't hold and lead
+ // to corruption.
+ // (Vec grows to next power of two)
+ //good- [9, 12, 15, X, X, X, X, |6]
+ //bug- [15, 12, X, X, X, |6, X, X]
+ assert_eq!(d3.pop_front(), Some(6));
+
+ // Which leads us to the following state which
+ // would be a failure case.
+ //bug- [15, 12, X, X, X, X, |X, X]
+ assert_eq!(d3.front(), Some(&9));
+ }
+
+ #[test]
+ fn test_reserve_exact() {
+ let mut d = RingBuf::new();
+ d.push(0u64);
+ d.reserve_exact(50);
+ assert_eq!(d.elts.capacity(), 50);
+ let mut d = RingBuf::new();
+ d.push(0u32);
+ d.reserve_exact(50);
+ assert_eq!(d.elts.capacity(), 50);
+ }
+
+ #[test]
+ fn test_reserve() {
+ let mut d = RingBuf::new();
+ d.push(0u64);
+ d.reserve(50);
+ assert_eq!(d.elts.capacity(), 64);
+ let mut d = RingBuf::new();
+ d.push(0u32);
+ d.reserve(50);
+ assert_eq!(d.elts.capacity(), 64);
+ }
+
+ #[test]
+ fn test_swap() {
+ let mut d: RingBuf<int> = range(0i, 5).collect();
+ d.pop_front();
+ d.swap(0, 3);
+ assert_eq!(d.iter().map(|&x|x).collect::<Vec<int>>(), vec!(4, 2, 3, 1));
+ }
+
+ #[test]
+ fn test_iter() {
+ let mut d = RingBuf::new();
+ assert_eq!(d.iter().next(), None);
+ assert_eq!(d.iter().size_hint(), (0, Some(0)));
+
+ for i in range(0i, 5) {
+ d.push(i);
+ }
+ {
+ let b: &[_] = &[&0,&1,&2,&3,&4];
+ assert_eq!(d.iter().collect::<Vec<&int>>().as_slice(), b);
+ }
+
+ for i in range(6i, 9) {
+ d.push_front(i);
+ }
+ {
+ let b: &[_] = &[&8,&7,&6,&0,&1,&2,&3,&4];
+ assert_eq!(d.iter().collect::<Vec<&int>>().as_slice(), b);
+ }
+
+ let mut it = d.iter();
+ let mut len = d.len();
+ loop {
+ match it.next() {
+ None => break,
+ _ => { len -= 1; assert_eq!(it.size_hint(), (len, Some(len))) }
+ }
+ }
+ }
+
+ #[test]
+ fn test_rev_iter() {
+ let mut d = RingBuf::new();
+ assert_eq!(d.iter().rev().next(), None);
+
+ for i in range(0i, 5) {
+ d.push(i);
+ }
+ {
+ let b: &[_] = &[&4,&3,&2,&1,&0];
+ assert_eq!(d.iter().rev().collect::<Vec<&int>>().as_slice(), b);
+ }
+
+ for i in range(6i, 9) {
+ d.push_front(i);
+ }
+ let b: &[_] = &[&4,&3,&2,&1,&0,&6,&7,&8];
+ assert_eq!(d.iter().rev().collect::<Vec<&int>>().as_slice(), b);
+ }
+
+ #[test]
+ fn test_mut_rev_iter_wrap() {
+ let mut d = RingBuf::with_capacity(3);
+ assert!(d.iter_mut().rev().next().is_none());
+
+ d.push(1i);
+ d.push(2);
+ d.push(3);
+ assert_eq!(d.pop_front(), Some(1));
+ d.push(4);
+
+ assert_eq!(d.iter_mut().rev().map(|x| *x).collect::<Vec<int>>(),
+ vec!(4, 3, 2));
+ }
+
+ #[test]
+ fn test_mut_iter() {
+ let mut d = RingBuf::new();
+ assert!(d.iter_mut().next().is_none());
+
+ for i in range(0u, 3) {
+ d.push_front(i);
+ }
+
+ for (i, elt) in d.iter_mut().enumerate() {
+ assert_eq!(*elt, 2 - i);
+ *elt = i;
+ }
+
+ {
+ let mut it = d.iter_mut();
+ assert_eq!(*it.next().unwrap(), 0);
+ assert_eq!(*it.next().unwrap(), 1);
+ assert_eq!(*it.next().unwrap(), 2);
+ assert!(it.next().is_none());
+ }
+ }
+
+ #[test]
+ fn test_mut_rev_iter() {
+ let mut d = RingBuf::new();
+ assert!(d.iter_mut().rev().next().is_none());
+
+ for i in range(0u, 3) {
+ d.push_front(i);
+ }
+
+ for (i, elt) in d.iter_mut().rev().enumerate() {
+ assert_eq!(*elt, i);
+ *elt = i;
+ }
+
+ {
+ let mut it = d.iter_mut().rev();
+ assert_eq!(*it.next().unwrap(), 0);
+ assert_eq!(*it.next().unwrap(), 1);
+ assert_eq!(*it.next().unwrap(), 2);
+ assert!(it.next().is_none());
+ }
+ }
+
+ #[test]
+ fn test_from_iter() {
+ use std::iter;
+ let v = vec!(1i,2,3,4,5,6,7);
+ let deq: RingBuf<int> = v.iter().map(|&x| x).collect();
+ let u: Vec<int> = deq.iter().map(|&x| x).collect();
+ assert_eq!(u, v);
+
+ let mut seq = iter::count(0u, 2).take(256);
+ let deq: RingBuf<uint> = seq.collect();
+ for (i, &x) in deq.iter().enumerate() {
+ assert_eq!(2*i, x);
+ }
+ assert_eq!(deq.len(), 256);
+ }
+
+ #[test]
+ fn test_clone() {
+ let mut d = RingBuf::new();
+ d.push_front(17i);
+ d.push_front(42);
+ d.push(137);
+ d.push(137);
+ assert_eq!(d.len(), 4u);
+ let mut e = d.clone();
+ assert_eq!(e.len(), 4u);
+ while !d.is_empty() {
+ assert_eq!(d.pop(), e.pop());
+ }
+ assert_eq!(d.len(), 0u);
+ assert_eq!(e.len(), 0u);
+ }
+
+ #[test]
+ fn test_eq() {
+ let mut d = RingBuf::new();
+ assert!(d == RingBuf::with_capacity(0));
+ d.push_front(137i);
+ d.push_front(17);
+ d.push_front(42);
+ d.push(137);
+ let mut e = RingBuf::with_capacity(0);
+ e.push(42);
+ e.push(17);
+ e.push(137);
+ e.push(137);
+ assert!(&e == &d);
+ e.pop();
+ e.push(0);
+ assert!(e != d);
+ e.clear();
+ assert!(e == RingBuf::new());
+ }
+
+ #[test]
+ fn test_hash() {
+ let mut x = RingBuf::new();
+ let mut y = RingBuf::new();
+
+ x.push(1i);
+ x.push(2);
+ x.push(3);
+
+ y.push(0i);
+ y.push(1i);
+ y.pop_front();
+ y.push(2);
+ y.push(3);
+
+ assert!(hash::hash(&x) == hash::hash(&y));
+ }
+
+ #[test]
+ fn test_ord() {
+ let x = RingBuf::new();
+ let mut y = RingBuf::new();
+ y.push(1i);
+ y.push(2);
+ y.push(3);
+ assert!(x < y);
+ assert!(y > x);
+ assert!(x <= x);
+ assert!(x >= x);
+ }
+
+ #[test]
+ fn test_show() {
+ let ringbuf: RingBuf<int> = range(0i, 10).collect();
+ assert!(format!("{}", ringbuf).as_slice() == "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
+
+ let ringbuf: RingBuf<&str> = vec!["just", "one", "test", "more"].iter()
+ .map(|&s| s)
+ .collect();
+ assert!(format!("{}", ringbuf).as_slice() == "[just, one, test, more]");
+ }
+}
+++ /dev/null
-// Copyright 2012-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.
-
-//! This crate implements a double-ended queue with `O(1)` amortized inserts and removals from both
-//! ends of the container. It also has `O(1)` indexing like a vector. The contained elements are
-//! not required to be copyable, and the queue will be sendable if the contained type is sendable.
-//! Its interface `Deque` is defined in `collections`.
-
-use core::prelude::*;
-
-use core::cmp;
-use core::default::Default;
-use core::fmt;
-use core::iter;
-use core::slice;
-use std::hash::{Writer, Hash};
-
-use vec::Vec;
-
-static INITIAL_CAPACITY: uint = 8u; // 2^3
-static MINIMUM_CAPACITY: uint = 2u;
-
-/// `RingBuf` is a circular buffer that implements `Deque`.
-#[deriving(Clone)]
-pub struct RingBuf<T> {
- nelts: uint,
- lo: uint,
- elts: Vec<Option<T>>
-}
-
-impl<T> Default for RingBuf<T> {
- #[inline]
- fn default() -> RingBuf<T> { RingBuf::new() }
-}
-
-impl<T> RingBuf<T> {
- /// Creates an empty `RingBuf`.
- pub fn new() -> RingBuf<T> {
- RingBuf::with_capacity(INITIAL_CAPACITY)
- }
-
- /// Creates an empty `RingBuf` with space for at least `n` elements.
- pub fn with_capacity(n: uint) -> RingBuf<T> {
- RingBuf{nelts: 0, lo: 0,
- elts: Vec::from_fn(cmp::max(MINIMUM_CAPACITY, n), |_| None)}
- }
-
- /// Retrieves an element in the `RingBuf` by index.
- ///
- /// Fails if there is no element with the given index.
- ///
- /// # Example
- ///
- /// ```rust
- /// # #![allow(deprecated)]
- /// use std::collections::RingBuf;
- ///
- /// let mut buf = RingBuf::new();
- /// buf.push(3i);
- /// buf.push(4);
- /// buf.push(5);
- /// *buf.get_mut(1) = 7;
- /// assert_eq!(buf[1], 7);
- /// ```
- #[deprecated = "use indexing instead: `buf[index] = value`"]
- pub fn get_mut(&mut self, i: uint) -> &mut T {
- &mut self[i]
- }
-
- /// Swaps elements at indices `i` and `j`.
- ///
- /// `i` and `j` may be equal.
- ///
- /// Fails if there is no element with either index.
- ///
- /// # Example
- ///
- /// ```rust
- /// use std::collections::RingBuf;
- ///
- /// let mut buf = RingBuf::new();
- /// buf.push(3i);
- /// buf.push(4);
- /// buf.push(5);
- /// buf.swap(0, 2);
- /// assert_eq!(buf[0], 5);
- /// assert_eq!(buf[2], 3);
- /// ```
- pub fn swap(&mut self, i: uint, j: uint) {
- assert!(i < self.len());
- assert!(j < self.len());
- let ri = self.raw_index(i);
- let rj = self.raw_index(j);
- self.elts.as_mut_slice().swap(ri, rj);
- }
-
- /// Returns the index in the underlying `Vec` for a given logical element
- /// index.
- fn raw_index(&self, idx: uint) -> uint {
- raw_index(self.lo, self.elts.len(), idx)
- }
-
- /// Reserves capacity for exactly `n` elements in the given `RingBuf`,
- /// doing nothing if `self`'s capacity is already equal to or greater
- /// than the requested capacity.
- pub fn reserve_exact(&mut self, n: uint) {
- self.elts.reserve_exact(n);
- }
-
- /// Reserves capacity for at least `n` elements in the given `RingBuf`,
- /// over-allocating in case the caller needs to reserve additional
- /// space.
- ///
- /// Do nothing if `self`'s capacity is already equal to or greater
- /// than the requested capacity.
- pub fn reserve(&mut self, n: uint) {
- self.elts.reserve(n);
- }
-
- /// Returns a front-to-back iterator.
- ///
- /// # Example
- ///
- /// ```rust
- /// use std::collections::RingBuf;
- ///
- /// let mut buf = RingBuf::new();
- /// buf.push(5i);
- /// buf.push(3);
- /// buf.push(4);
- /// let b: &[_] = &[&5, &3, &4];
- /// assert_eq!(buf.iter().collect::<Vec<&int>>().as_slice(), b);
- /// ```
- pub fn iter(&self) -> Items<T> {
- Items{index: 0, rindex: self.nelts, lo: self.lo, elts: self.elts.as_slice()}
- }
-
- /// Returns a front-to-back iterator which returns mutable references.
- ///
- /// # Example
- ///
- /// ```rust
- /// use std::collections::RingBuf;
- ///
- /// let mut buf = RingBuf::new();
- /// buf.push(5i);
- /// buf.push(3);
- /// buf.push(4);
- /// for num in buf.iter_mut() {
- /// *num = *num - 2;
- /// }
- /// let b: &[_] = &[&mut 3, &mut 1, &mut 2];
- /// assert_eq!(buf.iter_mut().collect::<Vec<&mut int>>()[], b);
- /// ```
- pub fn iter_mut(&mut self) -> MutItems<T> {
- let start_index = raw_index(self.lo, self.elts.len(), 0);
- let end_index = raw_index(self.lo, self.elts.len(), self.nelts);
-
- // Divide up the array
- if end_index <= start_index {
- // Items to iterate goes from:
- // start_index to self.elts.len()
- // and then
- // 0 to end_index
- let (temp, remaining1) = self.elts.split_at_mut(start_index);
- let (remaining2, _) = temp.split_at_mut(end_index);
- MutItems {
- remaining1: remaining1.iter_mut(),
- remaining2: remaining2.iter_mut(),
- nelts: self.nelts,
- }
- } else {
- // Items to iterate goes from start_index to end_index:
- let (empty, elts) = self.elts.split_at_mut(0);
- let remaining1 = elts[mut start_index..end_index];
- MutItems {
- remaining1: remaining1.iter_mut(),
- remaining2: empty.iter_mut(),
- nelts: self.nelts,
- }
- }
- }
-
- /// Returns the number of elements in the `RingBuf`.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::RingBuf;
- ///
- /// let mut v = RingBuf::new();
- /// assert_eq!(v.len(), 0);
- /// v.push(1i);
- /// assert_eq!(v.len(), 1);
- /// ```
- pub fn len(&self) -> uint { self.nelts }
-
- /// Returns true if the buffer contains no elements
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::RingBuf;
- ///
- /// let mut v = RingBuf::new();
- /// assert!(v.is_empty());
- /// v.push_front(1i);
- /// assert!(!v.is_empty());
- /// ```
- pub fn is_empty(&self) -> bool { self.len() == 0 }
-
- /// Clears the buffer, removing all values.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::RingBuf;
- ///
- /// let mut v = RingBuf::new();
- /// v.push(1i);
- /// v.clear();
- /// assert!(v.is_empty());
- /// ```
- pub fn clear(&mut self) {
- for x in self.elts.iter_mut() { *x = None }
- self.nelts = 0;
- self.lo = 0;
- }
-
- /// Provides a reference to the front element, or `None` if the sequence is
- /// empty.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::RingBuf;
- ///
- /// let mut d = RingBuf::new();
- /// assert_eq!(d.front(), None);
- ///
- /// d.push(1i);
- /// d.push(2i);
- /// assert_eq!(d.front(), Some(&1i));
- /// ```
- pub fn front(&self) -> Option<&T> {
- if self.nelts > 0 { Some(&self[0]) } else { None }
- }
-
- /// Provides a mutable reference to the front element, or `None` if the
- /// sequence is empty.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::RingBuf;
- ///
- /// let mut d = RingBuf::new();
- /// assert_eq!(d.front_mut(), None);
- ///
- /// d.push(1i);
- /// d.push(2i);
- /// match d.front_mut() {
- /// Some(x) => *x = 9i,
- /// None => (),
- /// }
- /// assert_eq!(d.front(), Some(&9i));
- /// ```
- pub fn front_mut(&mut self) -> Option<&mut T> {
- if self.nelts > 0 { Some(&mut self[0]) } else { None }
- }
-
- /// Provides a reference to the back element, or `None` if the sequence is
- /// empty.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::RingBuf;
- ///
- /// let mut d = RingBuf::new();
- /// assert_eq!(d.back(), None);
- ///
- /// d.push(1i);
- /// d.push(2i);
- /// assert_eq!(d.back(), Some(&2i));
- /// ```
- pub fn back(&self) -> Option<&T> {
- if self.nelts > 0 { Some(&self[self.nelts - 1]) } else { None }
- }
-
- /// Provides a mutable reference to the back element, or `None` if the
- /// sequence is empty.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::RingBuf;
- ///
- /// let mut d = RingBuf::new();
- /// assert_eq!(d.back(), None);
- ///
- /// d.push(1i);
- /// d.push(2i);
- /// match d.back_mut() {
- /// Some(x) => *x = 9i,
- /// None => (),
- /// }
- /// assert_eq!(d.back(), Some(&9i));
- /// ```
- pub fn back_mut(&mut self) -> Option<&mut T> {
- let nelts = self.nelts;
- if nelts > 0 { Some(&mut self[nelts - 1]) } else { None }
- }
-
- /// Removes the first element and returns it, or `None` if the sequence is
- /// empty.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::RingBuf;
- ///
- /// let mut d = RingBuf::new();
- /// d.push(1i);
- /// d.push(2i);
- ///
- /// assert_eq!(d.pop_front(), Some(1i));
- /// assert_eq!(d.pop_front(), Some(2i));
- /// assert_eq!(d.pop_front(), None);
- /// ```
- pub fn pop_front(&mut self) -> Option<T> {
- let result = self.elts[self.lo].take();
- if result.is_some() {
- self.lo = (self.lo + 1u) % self.elts.len();
- self.nelts -= 1u;
- }
- result
- }
-
- /// Inserts an element first in the sequence.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::RingBuf;
- ///
- /// let mut d = RingBuf::new();
- /// d.push_front(1i);
- /// d.push_front(2i);
- /// assert_eq!(d.front(), Some(&2i));
- /// ```
- pub fn push_front(&mut self, t: T) {
- if self.nelts == self.elts.len() {
- grow(self.nelts, &mut self.lo, &mut self.elts);
- }
- if self.lo == 0u {
- self.lo = self.elts.len() - 1u;
- } else { self.lo -= 1u; }
- self.elts[self.lo] = Some(t);
- self.nelts += 1u;
- }
-
- /// Appends an element to the back of a buffer
- ///
- /// # Example
- ///
- /// ```rust
- /// use std::collections::RingBuf;
- ///
- /// let mut buf = RingBuf::new();
- /// buf.push(1i);
- /// buf.push(3);
- /// assert_eq!(3, *buf.back().unwrap());
- /// ```
- pub fn push(&mut self, t: T) {
- if self.nelts == self.elts.len() {
- grow(self.nelts, &mut self.lo, &mut self.elts);
- }
- let hi = self.raw_index(self.nelts);
- self.elts[hi] = Some(t);
- self.nelts += 1u;
- }
-
- /// Removes the last element from a buffer and returns it, or `None` if
- /// it is empty.
- ///
- /// # Example
- ///
- /// ```rust
- /// use std::collections::RingBuf;
- ///
- /// let mut buf = RingBuf::new();
- /// assert_eq!(buf.pop(), None);
- /// buf.push(1i);
- /// buf.push(3);
- /// assert_eq!(buf.pop(), Some(3));
- /// ```
- pub fn pop(&mut self) -> Option<T> {
- if self.nelts > 0 {
- self.nelts -= 1;
- let hi = self.raw_index(self.nelts);
- self.elts[hi].take()
- } else {
- None
- }
- }
-}
-
-/// `RingBuf` iterator.
-pub struct Items<'a, T:'a> {
- lo: uint,
- index: uint,
- rindex: uint,
- elts: &'a [Option<T>],
-}
-
-impl<'a, T> Iterator<&'a T> for Items<'a, T> {
- #[inline]
- fn next(&mut self) -> Option<&'a T> {
- if self.index == self.rindex {
- return None;
- }
- let raw_index = raw_index(self.lo, self.elts.len(), self.index);
- self.index += 1;
- Some(self.elts[raw_index].as_ref().unwrap())
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- let len = self.rindex - self.index;
- (len, Some(len))
- }
-}
-
-impl<'a, T> DoubleEndedIterator<&'a T> for Items<'a, T> {
- #[inline]
- fn next_back(&mut self) -> Option<&'a T> {
- if self.index == self.rindex {
- return None;
- }
- self.rindex -= 1;
- let raw_index = raw_index(self.lo, self.elts.len(), self.rindex);
- Some(self.elts[raw_index].as_ref().unwrap())
- }
-}
-
-impl<'a, T> ExactSize<&'a T> for Items<'a, T> {}
-
-impl<'a, T> RandomAccessIterator<&'a T> for Items<'a, T> {
- #[inline]
- fn indexable(&self) -> uint { self.rindex - self.index }
-
- #[inline]
- fn idx(&mut self, j: uint) -> Option<&'a T> {
- if j >= self.indexable() {
- None
- } else {
- let raw_index = raw_index(self.lo, self.elts.len(), self.index + j);
- Some(self.elts[raw_index].as_ref().unwrap())
- }
- }
-}
-
-/// `RingBuf` mutable iterator.
-pub struct MutItems<'a, T:'a> {
- remaining1: slice::MutItems<'a, Option<T>>,
- remaining2: slice::MutItems<'a, Option<T>>,
- nelts: uint,
-}
-
-impl<'a, T> Iterator<&'a mut T> for MutItems<'a, T> {
- #[inline]
- fn next(&mut self) -> Option<&'a mut T> {
- if self.nelts == 0 {
- return None;
- }
- self.nelts -= 1;
- match self.remaining1.next() {
- Some(ptr) => return Some(ptr.as_mut().unwrap()),
- None => {}
- }
- match self.remaining2.next() {
- Some(ptr) => return Some(ptr.as_mut().unwrap()),
- None => unreachable!(),
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- (self.nelts, Some(self.nelts))
- }
-}
-
-impl<'a, T> DoubleEndedIterator<&'a mut T> for MutItems<'a, T> {
- #[inline]
- fn next_back(&mut self) -> Option<&'a mut T> {
- if self.nelts == 0 {
- return None;
- }
- self.nelts -= 1;
- match self.remaining2.next_back() {
- Some(ptr) => return Some(ptr.as_mut().unwrap()),
- None => {}
- }
- match self.remaining1.next_back() {
- Some(ptr) => return Some(ptr.as_mut().unwrap()),
- None => unreachable!(),
- }
- }
-}
-
-impl<'a, T> ExactSize<&'a mut T> for MutItems<'a, T> {}
-
-/// Grow is only called on full elts, so nelts is also len(elts), unlike
-/// elsewhere.
-fn grow<T>(nelts: uint, loptr: &mut uint, elts: &mut Vec<Option<T>>) {
- assert_eq!(nelts, elts.len());
- let lo = *loptr;
- elts.reserve(nelts * 2);
- let newlen = elts.capacity();
-
- /* fill with None */
- for _ in range(elts.len(), newlen) {
- elts.push(None);
- }
-
- /*
- Move the shortest half into the newly reserved area.
- lo ---->|
- nelts ----------->|
- [o o o|o o o o o]
- A [. . .|o o o o o o o o|. . . . .]
- B [o o o|. . . . . . . .|o o o o o]
- */
-
- assert!(newlen - nelts/2 >= nelts);
- if lo <= (nelts - lo) { // A
- for i in range(0u, lo) {
- elts.as_mut_slice().swap(i, nelts + i);
- }
- } else { // B
- for i in range(lo, nelts) {
- elts.as_mut_slice().swap(i, newlen - nelts + i);
- }
- *loptr += newlen - nelts;
- }
-}
-
-/// Returns the index in the underlying `Vec` for a given logical element index.
-fn raw_index(lo: uint, len: uint, index: uint) -> uint {
- if lo >= len - index {
- lo + index - len
- } else {
- lo + index
- }
-}
-
-impl<A: PartialEq> PartialEq for RingBuf<A> {
- fn eq(&self, other: &RingBuf<A>) -> bool {
- self.nelts == other.nelts &&
- self.iter().zip(other.iter()).all(|(a, b)| a.eq(b))
- }
- fn ne(&self, other: &RingBuf<A>) -> bool {
- !self.eq(other)
- }
-}
-
-impl<A: Eq> Eq for RingBuf<A> {}
-
-impl<A: PartialOrd> PartialOrd for RingBuf<A> {
- fn partial_cmp(&self, other: &RingBuf<A>) -> Option<Ordering> {
- iter::order::partial_cmp(self.iter(), other.iter())
- }
-}
-
-impl<A: Ord> Ord for RingBuf<A> {
- #[inline]
- fn cmp(&self, other: &RingBuf<A>) -> Ordering {
- iter::order::cmp(self.iter(), other.iter())
- }
-}
-
-impl<S: Writer, A: Hash<S>> Hash<S> for RingBuf<A> {
- fn hash(&self, state: &mut S) {
- self.len().hash(state);
- for elt in self.iter() {
- elt.hash(state);
- }
- }
-}
-
-impl<A> Index<uint, A> for RingBuf<A> {
- #[inline]
- fn index<'a>(&'a self, i: &uint) -> &'a A {
- let idx = self.raw_index(*i);
- match self.elts[idx] {
- None => panic!(),
- Some(ref v) => v,
- }
- }
-}
-
-impl<A> IndexMut<uint, A> for RingBuf<A> {
- #[inline]
- fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut A {
- let idx = self.raw_index(*i);
- match *(&mut self.elts[idx]) {
- None => panic!(),
- Some(ref mut v) => v
- }
- }
-}
-
-impl<A> FromIterator<A> for RingBuf<A> {
- fn from_iter<T: Iterator<A>>(iterator: T) -> RingBuf<A> {
- let (lower, _) = iterator.size_hint();
- let mut deq = RingBuf::with_capacity(lower);
- deq.extend(iterator);
- deq
- }
-}
-
-impl<A> Extendable<A> for RingBuf<A> {
- fn extend<T: Iterator<A>>(&mut self, mut iterator: T) {
- for elt in iterator {
- self.push(elt);
- }
- }
-}
-
-impl<T: fmt::Show> fmt::Show for RingBuf<T> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- try!(write!(f, "["));
-
- for (i, e) in self.iter().enumerate() {
- if i != 0 { try!(write!(f, ", ")); }
- try!(write!(f, "{}", *e));
- }
-
- write!(f, "]")
- }
-}
-
-#[cfg(test)]
-mod tests {
- use std::fmt::Show;
- use std::prelude::*;
- use std::hash;
- use test::Bencher;
- use test;
-
- use super::RingBuf;
- use vec::Vec;
-
- #[test]
- #[allow(deprecated)]
- fn test_simple() {
- let mut d = RingBuf::new();
- assert_eq!(d.len(), 0u);
- d.push_front(17i);
- d.push_front(42i);
- d.push(137);
- assert_eq!(d.len(), 3u);
- d.push(137);
- assert_eq!(d.len(), 4u);
- debug!("{}", d.front());
- assert_eq!(*d.front().unwrap(), 42);
- debug!("{}", d.back());
- assert_eq!(*d.back().unwrap(), 137);
- let mut i = d.pop_front();
- debug!("{}", i);
- assert_eq!(i, Some(42));
- i = d.pop();
- debug!("{}", i);
- assert_eq!(i, Some(137));
- i = d.pop();
- debug!("{}", i);
- assert_eq!(i, Some(137));
- i = d.pop();
- debug!("{}", i);
- assert_eq!(i, Some(17));
- assert_eq!(d.len(), 0u);
- d.push(3);
- assert_eq!(d.len(), 1u);
- d.push_front(2);
- assert_eq!(d.len(), 2u);
- d.push(4);
- assert_eq!(d.len(), 3u);
- d.push_front(1);
- assert_eq!(d.len(), 4u);
- debug!("{}", d[0]);
- debug!("{}", d[1]);
- debug!("{}", d[2]);
- debug!("{}", d[3]);
- assert_eq!(d[0], 1);
- assert_eq!(d[1], 2);
- assert_eq!(d[2], 3);
- assert_eq!(d[3], 4);
- }
-
- #[cfg(test)]
- fn test_parameterized<T:Clone + PartialEq + Show>(a: T, b: T, c: T, d: T) {
- let mut deq = RingBuf::new();
- assert_eq!(deq.len(), 0);
- deq.push_front(a.clone());
- deq.push_front(b.clone());
- deq.push(c.clone());
- assert_eq!(deq.len(), 3);
- deq.push(d.clone());
- assert_eq!(deq.len(), 4);
- assert_eq!((*deq.front().unwrap()).clone(), b.clone());
- assert_eq!((*deq.back().unwrap()).clone(), d.clone());
- assert_eq!(deq.pop_front().unwrap(), b.clone());
- assert_eq!(deq.pop().unwrap(), d.clone());
- assert_eq!(deq.pop().unwrap(), c.clone());
- assert_eq!(deq.pop().unwrap(), a.clone());
- assert_eq!(deq.len(), 0);
- deq.push(c.clone());
- assert_eq!(deq.len(), 1);
- deq.push_front(b.clone());
- assert_eq!(deq.len(), 2);
- deq.push(d.clone());
- assert_eq!(deq.len(), 3);
- deq.push_front(a.clone());
- assert_eq!(deq.len(), 4);
- assert_eq!(deq[0].clone(), a.clone());
- assert_eq!(deq[1].clone(), b.clone());
- assert_eq!(deq[2].clone(), c.clone());
- assert_eq!(deq[3].clone(), d.clone());
- }
-
- #[test]
- fn test_push_front_grow() {
- let mut deq = RingBuf::new();
- for i in range(0u, 66) {
- deq.push_front(i);
- }
- assert_eq!(deq.len(), 66);
-
- for i in range(0u, 66) {
- assert_eq!(deq[i], 65 - i);
- }
-
- let mut deq = RingBuf::new();
- for i in range(0u, 66) {
- deq.push(i);
- }
-
- for i in range(0u, 66) {
- assert_eq!(deq[i], i);
- }
- }
-
- #[test]
- fn test_index() {
- let mut deq = RingBuf::new();
- for i in range(1u, 4) {
- deq.push_front(i);
- }
- assert_eq!(deq[1], 2);
- }
-
- #[test]
- #[should_fail]
- fn test_index_out_of_bounds() {
- let mut deq = RingBuf::new();
- for i in range(1u, 4) {
- deq.push_front(i);
- }
- deq[3];
- }
-
- #[bench]
- fn bench_new(b: &mut test::Bencher) {
- b.iter(|| {
- let _: RingBuf<u64> = RingBuf::new();
- })
- }
-
- #[bench]
- fn bench_push_back(b: &mut test::Bencher) {
- let mut deq = RingBuf::new();
- b.iter(|| {
- deq.push(0i);
- })
- }
-
- #[bench]
- fn bench_push_front(b: &mut test::Bencher) {
- let mut deq = RingBuf::new();
- b.iter(|| {
- deq.push_front(0i);
- })
- }
-
- #[bench]
- fn bench_grow(b: &mut test::Bencher) {
- let mut deq = RingBuf::new();
- b.iter(|| {
- for _ in range(0i, 65) {
- deq.push_front(1i);
- }
- })
- }
-
- #[deriving(Clone, PartialEq, Show)]
- enum Taggy {
- One(int),
- Two(int, int),
- Three(int, int, int),
- }
-
- #[deriving(Clone, PartialEq, Show)]
- enum Taggypar<T> {
- Onepar(int),
- Twopar(int, int),
- Threepar(int, int, int),
- }
-
- #[deriving(Clone, PartialEq, Show)]
- struct RecCy {
- x: int,
- y: int,
- t: Taggy
- }
-
- #[test]
- fn test_param_int() {
- test_parameterized::<int>(5, 72, 64, 175);
- }
-
- #[test]
- fn test_param_taggy() {
- test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3), Two(17, 42));
- }
-
- #[test]
- fn test_param_taggypar() {
- test_parameterized::<Taggypar<int>>(Onepar::<int>(1),
- Twopar::<int>(1, 2),
- Threepar::<int>(1, 2, 3),
- Twopar::<int>(17, 42));
- }
-
- #[test]
- fn test_param_reccy() {
- let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
- let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
- let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
- let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
- test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
- }
-
- #[test]
- fn test_with_capacity() {
- let mut d = RingBuf::with_capacity(0);
- d.push(1i);
- assert_eq!(d.len(), 1);
- let mut d = RingBuf::with_capacity(50);
- d.push(1i);
- assert_eq!(d.len(), 1);
- }
-
- #[test]
- fn test_with_capacity_non_power_two() {
- let mut d3 = RingBuf::with_capacity(3);
- d3.push(1i);
-
- // X = None, | = lo
- // [|1, X, X]
- assert_eq!(d3.pop_front(), Some(1));
- // [X, |X, X]
- assert_eq!(d3.front(), None);
-
- // [X, |3, X]
- d3.push(3);
- // [X, |3, 6]
- d3.push(6);
- // [X, X, |6]
- assert_eq!(d3.pop_front(), Some(3));
-
- // Pushing the lo past half way point to trigger
- // the 'B' scenario for growth
- // [9, X, |6]
- d3.push(9);
- // [9, 12, |6]
- d3.push(12);
-
- d3.push(15);
- // There used to be a bug here about how the
- // RingBuf made growth assumptions about the
- // underlying Vec which didn't hold and lead
- // to corruption.
- // (Vec grows to next power of two)
- //good- [9, 12, 15, X, X, X, X, |6]
- //bug- [15, 12, X, X, X, |6, X, X]
- assert_eq!(d3.pop_front(), Some(6));
-
- // Which leads us to the following state which
- // would be a failure case.
- //bug- [15, 12, X, X, X, X, |X, X]
- assert_eq!(d3.front(), Some(&9));
- }
-
- #[test]
- fn test_reserve_exact() {
- let mut d = RingBuf::new();
- d.push(0u64);
- d.reserve_exact(50);
- assert_eq!(d.elts.capacity(), 50);
- let mut d = RingBuf::new();
- d.push(0u32);
- d.reserve_exact(50);
- assert_eq!(d.elts.capacity(), 50);
- }
-
- #[test]
- fn test_reserve() {
- let mut d = RingBuf::new();
- d.push(0u64);
- d.reserve(50);
- assert_eq!(d.elts.capacity(), 64);
- let mut d = RingBuf::new();
- d.push(0u32);
- d.reserve(50);
- assert_eq!(d.elts.capacity(), 64);
- }
-
- #[test]
- fn test_swap() {
- let mut d: RingBuf<int> = range(0i, 5).collect();
- d.pop_front();
- d.swap(0, 3);
- assert_eq!(d.iter().map(|&x|x).collect::<Vec<int>>(), vec!(4, 2, 3, 1));
- }
-
- #[test]
- fn test_iter() {
- let mut d = RingBuf::new();
- assert_eq!(d.iter().next(), None);
- assert_eq!(d.iter().size_hint(), (0, Some(0)));
-
- for i in range(0i, 5) {
- d.push(i);
- }
- {
- let b: &[_] = &[&0,&1,&2,&3,&4];
- assert_eq!(d.iter().collect::<Vec<&int>>().as_slice(), b);
- }
-
- for i in range(6i, 9) {
- d.push_front(i);
- }
- {
- let b: &[_] = &[&8,&7,&6,&0,&1,&2,&3,&4];
- assert_eq!(d.iter().collect::<Vec<&int>>().as_slice(), b);
- }
-
- let mut it = d.iter();
- let mut len = d.len();
- loop {
- match it.next() {
- None => break,
- _ => { len -= 1; assert_eq!(it.size_hint(), (len, Some(len))) }
- }
- }
- }
-
- #[test]
- fn test_rev_iter() {
- let mut d = RingBuf::new();
- assert_eq!(d.iter().rev().next(), None);
-
- for i in range(0i, 5) {
- d.push(i);
- }
- {
- let b: &[_] = &[&4,&3,&2,&1,&0];
- assert_eq!(d.iter().rev().collect::<Vec<&int>>().as_slice(), b);
- }
-
- for i in range(6i, 9) {
- d.push_front(i);
- }
- let b: &[_] = &[&4,&3,&2,&1,&0,&6,&7,&8];
- assert_eq!(d.iter().rev().collect::<Vec<&int>>().as_slice(), b);
- }
-
- #[test]
- fn test_mut_rev_iter_wrap() {
- let mut d = RingBuf::with_capacity(3);
- assert!(d.iter_mut().rev().next().is_none());
-
- d.push(1i);
- d.push(2);
- d.push(3);
- assert_eq!(d.pop_front(), Some(1));
- d.push(4);
-
- assert_eq!(d.iter_mut().rev().map(|x| *x).collect::<Vec<int>>(),
- vec!(4, 3, 2));
- }
-
- #[test]
- fn test_mut_iter() {
- let mut d = RingBuf::new();
- assert!(d.iter_mut().next().is_none());
-
- for i in range(0u, 3) {
- d.push_front(i);
- }
-
- for (i, elt) in d.iter_mut().enumerate() {
- assert_eq!(*elt, 2 - i);
- *elt = i;
- }
-
- {
- let mut it = d.iter_mut();
- assert_eq!(*it.next().unwrap(), 0);
- assert_eq!(*it.next().unwrap(), 1);
- assert_eq!(*it.next().unwrap(), 2);
- assert!(it.next().is_none());
- }
- }
-
- #[test]
- fn test_mut_rev_iter() {
- let mut d = RingBuf::new();
- assert!(d.iter_mut().rev().next().is_none());
-
- for i in range(0u, 3) {
- d.push_front(i);
- }
-
- for (i, elt) in d.iter_mut().rev().enumerate() {
- assert_eq!(*elt, i);
- *elt = i;
- }
-
- {
- let mut it = d.iter_mut().rev();
- assert_eq!(*it.next().unwrap(), 0);
- assert_eq!(*it.next().unwrap(), 1);
- assert_eq!(*it.next().unwrap(), 2);
- assert!(it.next().is_none());
- }
- }
-
- #[test]
- fn test_from_iter() {
- use std::iter;
- let v = vec!(1i,2,3,4,5,6,7);
- let deq: RingBuf<int> = v.iter().map(|&x| x).collect();
- let u: Vec<int> = deq.iter().map(|&x| x).collect();
- assert_eq!(u, v);
-
- let mut seq = iter::count(0u, 2).take(256);
- let deq: RingBuf<uint> = seq.collect();
- for (i, &x) in deq.iter().enumerate() {
- assert_eq!(2*i, x);
- }
- assert_eq!(deq.len(), 256);
- }
-
- #[test]
- fn test_clone() {
- let mut d = RingBuf::new();
- d.push_front(17i);
- d.push_front(42);
- d.push(137);
- d.push(137);
- assert_eq!(d.len(), 4u);
- let mut e = d.clone();
- assert_eq!(e.len(), 4u);
- while !d.is_empty() {
- assert_eq!(d.pop(), e.pop());
- }
- assert_eq!(d.len(), 0u);
- assert_eq!(e.len(), 0u);
- }
-
- #[test]
- fn test_eq() {
- let mut d = RingBuf::new();
- assert!(d == RingBuf::with_capacity(0));
- d.push_front(137i);
- d.push_front(17);
- d.push_front(42);
- d.push(137);
- let mut e = RingBuf::with_capacity(0);
- e.push(42);
- e.push(17);
- e.push(137);
- e.push(137);
- assert!(&e == &d);
- e.pop();
- e.push(0);
- assert!(e != d);
- e.clear();
- assert!(e == RingBuf::new());
- }
-
- #[test]
- fn test_hash() {
- let mut x = RingBuf::new();
- let mut y = RingBuf::new();
-
- x.push(1i);
- x.push(2);
- x.push(3);
-
- y.push(0i);
- y.push(1i);
- y.pop_front();
- y.push(2);
- y.push(3);
-
- assert!(hash::hash(&x) == hash::hash(&y));
- }
-
- #[test]
- fn test_ord() {
- let x = RingBuf::new();
- let mut y = RingBuf::new();
- y.push(1i);
- y.push(2);
- y.push(3);
- assert!(x < y);
- assert!(y > x);
- assert!(x <= x);
- assert!(x >= x);
- }
-
- #[test]
- fn test_show() {
- let ringbuf: RingBuf<int> = range(0i, 10).collect();
- assert!(format!("{}", ringbuf).as_slice() == "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
-
- let ringbuf: RingBuf<&str> = vec!["just", "one", "test", "more"].iter()
- .map(|&s| s)
- .collect();
- assert!(format!("{}", ringbuf).as_slice() == "[just, one, test, more]");
- }
-}
+++ /dev/null
-// Copyright 2012-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.
-
-//! A simple map based on a vector for small integer keys. Space requirements
-//! are O(highest integer key).
-
-#![allow(missing_docs)]
-
-use core::prelude::*;
-
-use core::default::Default;
-use core::fmt;
-use core::iter;
-use core::iter::{Enumerate, FilterMap};
-use core::mem::replace;
-
-use {vec, slice};
-use vec::Vec;
-use hash;
-use hash::Hash;
-
-/// A map optimized for small integer keys.
-///
-/// # Example
-///
-/// ```
-/// use std::collections::SmallIntMap;
-///
-/// let mut months = SmallIntMap::new();
-/// months.insert(1, "Jan");
-/// months.insert(2, "Feb");
-/// months.insert(3, "Mar");
-///
-/// if !months.contains_key(&12) {
-/// println!("The end is near!");
-/// }
-///
-/// assert_eq!(months.find(&1), Some(&"Jan"));
-///
-/// match months.find_mut(&3) {
-/// Some(value) => *value = "Venus",
-/// None => (),
-/// }
-///
-/// assert_eq!(months.find(&3), Some(&"Venus"));
-///
-/// // Print out all months
-/// for (key, value) in months.iter() {
-/// println!("month {} is {}", key, value);
-/// }
-///
-/// months.clear();
-/// assert!(months.is_empty());
-/// ```
-#[deriving(PartialEq, Eq)]
-pub struct SmallIntMap<T> {
- v: Vec<Option<T>>,
-}
-
-impl<V> Default for SmallIntMap<V> {
- #[inline]
- fn default() -> SmallIntMap<V> { SmallIntMap::new() }
-}
-
-impl<V:Clone> Clone for SmallIntMap<V> {
- #[inline]
- fn clone(&self) -> SmallIntMap<V> {
- SmallIntMap { v: self.v.clone() }
- }
-
- #[inline]
- fn clone_from(&mut self, source: &SmallIntMap<V>) {
- self.v.reserve(source.v.len());
- for (i, w) in self.v.iter_mut().enumerate() {
- *w = source.v[i].clone();
- }
- }
-}
-
-impl <S: hash::Writer, T: Hash<S>> Hash<S> for SmallIntMap<T> {
- fn hash(&self, state: &mut S) {
- self.v.hash(state)
- }
-}
-
-impl<V> SmallIntMap<V> {
- /// Creates an empty `SmallIntMap`.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::SmallIntMap;
- /// let mut map: SmallIntMap<&str> = SmallIntMap::new();
- /// ```
- pub fn new() -> SmallIntMap<V> { SmallIntMap{v: vec!()} }
-
- /// Creates an empty `SmallIntMap` with space for at least `capacity`
- /// elements before resizing.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::SmallIntMap;
- /// let mut map: SmallIntMap<&str> = SmallIntMap::with_capacity(10);
- /// ```
- pub fn with_capacity(capacity: uint) -> SmallIntMap<V> {
- SmallIntMap { v: Vec::with_capacity(capacity) }
- }
-
- /// Returns an iterator visiting all keys in ascending order by the keys.
- /// The iterator's element type is `uint`.
- pub fn keys<'r>(&'r self) -> Keys<'r, V> {
- self.iter().map(|(k, _v)| k)
- }
-
- /// Returns an iterator visiting all values in ascending order by the keys.
- /// The iterator's element type is `&'r V`.
- pub fn values<'r>(&'r self) -> Values<'r, V> {
- self.iter().map(|(_k, v)| v)
- }
-
- /// Returns an iterator visiting all key-value pairs in ascending order by the keys.
- /// The iterator's element type is `(uint, &'r V)`.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::SmallIntMap;
- ///
- /// let mut map = SmallIntMap::new();
- /// map.insert(1, "a");
- /// map.insert(3, "c");
- /// map.insert(2, "b");
- ///
- /// // Print `1: a` then `2: b` then `3: c`
- /// for (key, value) in map.iter() {
- /// println!("{}: {}", key, value);
- /// }
- /// ```
- pub fn iter<'r>(&'r self) -> Entries<'r, V> {
- Entries {
- front: 0,
- back: self.v.len(),
- iter: self.v.iter()
- }
- }
-
- /// Returns an iterator visiting all key-value pairs in ascending order by the keys,
- /// with mutable references to the values.
- /// The iterator's element type is `(uint, &'r mut V)`.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::SmallIntMap;
- ///
- /// let mut map = SmallIntMap::new();
- /// map.insert(1, "a");
- /// map.insert(2, "b");
- /// map.insert(3, "c");
- ///
- /// for (key, value) in map.iter_mut() {
- /// *value = "x";
- /// }
- ///
- /// for (key, value) in map.iter() {
- /// assert_eq!(value, &"x");
- /// }
- /// ```
- pub fn iter_mut<'r>(&'r mut self) -> MutEntries<'r, V> {
- MutEntries {
- front: 0,
- back: self.v.len(),
- iter: self.v.iter_mut()
- }
- }
-
- /// Returns an iterator visiting all key-value pairs in ascending order by
- /// the keys, emptying (but not consuming) the original `SmallIntMap`.
- /// The iterator's element type is `(uint, &'r V)`.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::SmallIntMap;
- ///
- /// let mut map = SmallIntMap::new();
- /// map.insert(1, "a");
- /// map.insert(3, "c");
- /// map.insert(2, "b");
- ///
- /// // Not possible with .iter()
- /// let vec: Vec<(uint, &str)> = map.into_iter().collect();
- ///
- /// assert_eq!(vec, vec![(1, "a"), (2, "b"), (3, "c")]);
- /// ```
- pub fn into_iter(&mut self)
- -> FilterMap<(uint, Option<V>), (uint, V),
- Enumerate<vec::MoveItems<Option<V>>>>
- {
- let values = replace(&mut self.v, vec!());
- values.into_iter().enumerate().filter_map(|(i, v)| {
- v.map(|v| (i, v))
- })
- }
-
- /// Return the number of elements in the map.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::SmallIntMap;
- ///
- /// let mut a = SmallIntMap::new();
- /// assert_eq!(a.len(), 0);
- /// a.insert(1, "a");
- /// assert_eq!(a.len(), 1);
- /// ```
- pub fn len(&self) -> uint {
- self.v.iter().filter(|elt| elt.is_some()).count()
- }
-
- /// Return true if the map contains no elements.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::SmallIntMap;
- ///
- /// let mut a = SmallIntMap::new();
- /// assert!(a.is_empty());
- /// a.insert(1, "a");
- /// assert!(!a.is_empty());
- /// ```
- pub fn is_empty(&self) -> bool {
- self.v.iter().all(|elt| elt.is_none())
- }
-
- /// Clears the map, removing all key-value pairs.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::SmallIntMap;
- ///
- /// let mut a = SmallIntMap::new();
- /// a.insert(1, "a");
- /// a.clear();
- /// assert!(a.is_empty());
- /// ```
- pub fn clear(&mut self) { self.v.clear() }
-
- /// Returns a reference to the value corresponding to the key.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::SmallIntMap;
- ///
- /// let mut map = SmallIntMap::new();
- /// map.insert(1, "a");
- /// assert_eq!(map.find(&1), Some(&"a"));
- /// assert_eq!(map.find(&2), None);
- /// ```
- pub fn find<'a>(&'a self, key: &uint) -> Option<&'a V> {
- if *key < self.v.len() {
- match self.v[*key] {
- Some(ref value) => Some(value),
- None => None
- }
- } else {
- None
- }
- }
-
- /// Returns true if the map contains a value for the specified key.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::SmallIntMap;
- ///
- /// let mut map = SmallIntMap::new();
- /// map.insert(1, "a");
- /// assert_eq!(map.contains_key(&1), true);
- /// assert_eq!(map.contains_key(&2), false);
- /// ```
- #[inline]
- pub fn contains_key(&self, key: &uint) -> bool {
- self.find(key).is_some()
- }
-
- /// Returns a mutable reference to the value corresponding to the key.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::SmallIntMap;
- ///
- /// let mut map = SmallIntMap::new();
- /// map.insert(1, "a");
- /// match map.find_mut(&1) {
- /// Some(x) => *x = "b",
- /// None => (),
- /// }
- /// assert_eq!(map[1], "b");
- /// ```
- pub fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut V> {
- if *key < self.v.len() {
- match *(&mut self.v[*key]) {
- Some(ref mut value) => Some(value),
- None => None
- }
- } else {
- None
- }
- }
-
- /// Inserts a key-value pair into the map. An existing value for a
- /// key is replaced by the new value. Returns `true` if the key did
- /// not already exist in the map.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::SmallIntMap;
- ///
- /// let mut map = SmallIntMap::new();
- /// assert_eq!(map.insert(2, "value"), true);
- /// assert_eq!(map.insert(2, "value2"), false);
- /// assert_eq!(map[2], "value2");
- /// ```
- pub fn insert(&mut self, key: uint, value: V) -> bool {
- let exists = self.contains_key(&key);
- let len = self.v.len();
- if len <= key {
- self.v.grow_fn(key - len + 1, |_| None);
- }
- self.v[key] = Some(value);
- !exists
- }
-
- /// Removes a key-value pair from the map. Returns `true` if the key
- /// was present in the map.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::SmallIntMap;
- ///
- /// let mut map = SmallIntMap::new();
- /// assert_eq!(map.remove(&1), false);
- /// map.insert(1, "a");
- /// assert_eq!(map.remove(&1), true);
- /// ```
- pub fn remove(&mut self, key: &uint) -> bool {
- self.pop(key).is_some()
- }
-
- /// Inserts a key-value pair from the map. If the key already had a value
- /// present in the map, that value is returned. Otherwise, `None` is returned.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::SmallIntMap;
- ///
- /// let mut map = SmallIntMap::new();
- /// assert_eq!(map.swap(37, "a"), None);
- /// assert_eq!(map.is_empty(), false);
- ///
- /// map.insert(37, "b");
- /// assert_eq!(map.swap(37, "c"), Some("b"));
- /// assert_eq!(map[37], "c");
- /// ```
- pub fn swap(&mut self, key: uint, value: V) -> Option<V> {
- match self.find_mut(&key) {
- Some(loc) => { return Some(replace(loc, value)); }
- None => ()
- }
- self.insert(key, value);
- return None;
- }
-
- /// Removes a key from the map, returning the value at the key if the key
- /// was previously in the map.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::SmallIntMap;
- ///
- /// let mut map = SmallIntMap::new();
- /// map.insert(1, "a");
- /// assert_eq!(map.pop(&1), Some("a"));
- /// assert_eq!(map.pop(&1), None);
- /// ```
- pub fn pop(&mut self, key: &uint) -> Option<V> {
- if *key >= self.v.len() {
- return None;
- }
- self.v[*key].take()
- }
-}
-
-impl<V:Clone> SmallIntMap<V> {
- /// Updates a value in the map. If the key already exists in the map,
- /// modifies the value with `ff` taking `oldval, newval`.
- /// Otherwise, sets the value to `newval`.
- /// Returns `true` if the key did not already exist in the map.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::SmallIntMap;
- ///
- /// let mut map = SmallIntMap::new();
- ///
- /// // Key does not exist, will do a simple insert
- /// assert!(map.update(1, vec![1i, 2], |mut old, new| { old.extend(new.into_iter()); old }));
- /// assert_eq!(map[1], vec![1i, 2]);
- ///
- /// // Key exists, update the value
- /// assert!(!map.update(1, vec![3i, 4], |mut old, new| { old.extend(new.into_iter()); old }));
- /// assert_eq!(map[1], vec![1i, 2, 3, 4]);
- /// ```
- pub fn update(&mut self, key: uint, newval: V, ff: |V, V| -> V) -> bool {
- self.update_with_key(key, newval, |_k, v, v1| ff(v,v1))
- }
-
- /// Updates a value in the map. If the key already exists in the map,
- /// modifies the value with `ff` taking `key, oldval, newval`.
- /// Otherwise, sets the value to `newval`.
- /// Returns `true` if the key did not already exist in the map.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::SmallIntMap;
- ///
- /// let mut map = SmallIntMap::new();
- ///
- /// // Key does not exist, will do a simple insert
- /// assert!(map.update_with_key(7, 10, |key, old, new| (old + new) % key));
- /// assert_eq!(map[7], 10);
- ///
- /// // Key exists, update the value
- /// assert!(!map.update_with_key(7, 20, |key, old, new| (old + new) % key));
- /// assert_eq!(map[7], 2);
- /// ```
- pub fn update_with_key(&mut self,
- key: uint,
- val: V,
- ff: |uint, V, V| -> V)
- -> bool {
- let new_val = match self.find(&key) {
- None => val,
- Some(orig) => ff(key, (*orig).clone(), val)
- };
- self.insert(key, new_val)
- }
-}
-
-impl<V: PartialOrd> PartialOrd for SmallIntMap<V> {
- #[inline]
- fn partial_cmp(&self, other: &SmallIntMap<V>) -> Option<Ordering> {
- iter::order::partial_cmp(self.iter(), other.iter())
- }
-}
-
-impl<V: Ord> Ord for SmallIntMap<V> {
- #[inline]
- fn cmp(&self, other: &SmallIntMap<V>) -> Ordering {
- iter::order::cmp(self.iter(), other.iter())
- }
-}
-
-impl<V: fmt::Show> fmt::Show for SmallIntMap<V> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- try!(write!(f, "{{"));
-
- for (i, (k, v)) in self.iter().enumerate() {
- if i != 0 { try!(write!(f, ", ")); }
- try!(write!(f, "{}: {}", k, *v));
- }
-
- write!(f, "}}")
- }
-}
-
-impl<V> FromIterator<(uint, V)> for SmallIntMap<V> {
- fn from_iter<Iter: Iterator<(uint, V)>>(iter: Iter) -> SmallIntMap<V> {
- let mut map = SmallIntMap::new();
- map.extend(iter);
- map
- }
-}
-
-impl<V> Extendable<(uint, V)> for SmallIntMap<V> {
- fn extend<Iter: Iterator<(uint, V)>>(&mut self, mut iter: Iter) {
- for (k, v) in iter {
- self.insert(k, v);
- }
- }
-}
-
-impl<V> Index<uint, V> for SmallIntMap<V> {
- #[inline]
- fn index<'a>(&'a self, i: &uint) -> &'a V {
- self.find(i).expect("key not present")
- }
-}
-
-impl<V> IndexMut<uint, V> for SmallIntMap<V> {
- #[inline]
- fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut V {
- self.find_mut(i).expect("key not present")
- }
-}
-
-macro_rules! iterator {
- (impl $name:ident -> $elem:ty, $($getter:ident),+) => {
- impl<'a, T> Iterator<$elem> for $name<'a, T> {
- #[inline]
- fn next(&mut self) -> Option<$elem> {
- while self.front < self.back {
- match self.iter.next() {
- Some(elem) => {
- if elem.is_some() {
- let index = self.front;
- self.front += 1;
- return Some((index, elem $(. $getter ())+));
- }
- }
- _ => ()
- }
- self.front += 1;
- }
- None
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- (0, Some(self.back - self.front))
- }
- }
- }
-}
-
-macro_rules! double_ended_iterator {
- (impl $name:ident -> $elem:ty, $($getter:ident),+) => {
- impl<'a, T> DoubleEndedIterator<$elem> for $name<'a, T> {
- #[inline]
- fn next_back(&mut self) -> Option<$elem> {
- while self.front < self.back {
- match self.iter.next_back() {
- Some(elem) => {
- if elem.is_some() {
- self.back -= 1;
- return Some((self.back, elem$(. $getter ())+));
- }
- }
- _ => ()
- }
- self.back -= 1;
- }
- None
- }
- }
- }
-}
-
-/// Forward iterator over a map.
-pub struct Entries<'a, T:'a> {
- front: uint,
- back: uint,
- iter: slice::Items<'a, Option<T>>
-}
-
-iterator!(impl Entries -> (uint, &'a T), as_ref, unwrap)
-double_ended_iterator!(impl Entries -> (uint, &'a T), as_ref, unwrap)
-
-/// Forward iterator over the key-value pairs of a map, with the
-/// values being mutable.
-pub struct MutEntries<'a, T:'a> {
- front: uint,
- back: uint,
- iter: slice::MutItems<'a, Option<T>>
-}
-
-iterator!(impl MutEntries -> (uint, &'a mut T), as_mut, unwrap)
-double_ended_iterator!(impl MutEntries -> (uint, &'a mut T), as_mut, unwrap)
-
-/// Forward iterator over the keys of a map
-pub type Keys<'a, T> =
- iter::Map<'static, (uint, &'a T), uint, Entries<'a, T>>;
-
-/// Forward iterator over the values of a map
-pub type Values<'a, T> =
- iter::Map<'static, (uint, &'a T), &'a T, Entries<'a, T>>;
-
-#[cfg(test)]
-mod test_map {
- use std::prelude::*;
- use vec::Vec;
- use hash;
-
- use super::SmallIntMap;
-
- #[test]
- fn test_find_mut() {
- let mut m = SmallIntMap::new();
- assert!(m.insert(1, 12i));
- assert!(m.insert(2, 8));
- assert!(m.insert(5, 14));
- let new = 100;
- match m.find_mut(&5) {
- None => panic!(), Some(x) => *x = new
- }
- assert_eq!(m.find(&5), Some(&new));
- }
-
- #[test]
- fn test_len() {
- let mut map = SmallIntMap::new();
- assert_eq!(map.len(), 0);
- assert!(map.is_empty());
- assert!(map.insert(5, 20i));
- assert_eq!(map.len(), 1);
- assert!(!map.is_empty());
- assert!(map.insert(11, 12));
- assert_eq!(map.len(), 2);
- assert!(!map.is_empty());
- assert!(map.insert(14, 22));
- assert_eq!(map.len(), 3);
- assert!(!map.is_empty());
- }
-
- #[test]
- fn test_clear() {
- let mut map = SmallIntMap::new();
- assert!(map.insert(5, 20i));
- assert!(map.insert(11, 12));
- assert!(map.insert(14, 22));
- map.clear();
- assert!(map.is_empty());
- assert!(map.find(&5).is_none());
- assert!(map.find(&11).is_none());
- assert!(map.find(&14).is_none());
- }
-
- #[test]
- fn test_insert_with_key() {
- let mut map = SmallIntMap::new();
-
- // given a new key, initialize it with this new count,
- // given an existing key, add more to its count
- fn add_more_to_count(_k: uint, v0: uint, v1: uint) -> uint {
- v0 + v1
- }
-
- fn add_more_to_count_simple(v0: uint, v1: uint) -> uint {
- v0 + v1
- }
-
- // count integers
- map.update(3, 1, add_more_to_count_simple);
- map.update_with_key(9, 1, add_more_to_count);
- map.update(3, 7, add_more_to_count_simple);
- map.update_with_key(5, 3, add_more_to_count);
- map.update_with_key(3, 2, add_more_to_count);
-
- // check the total counts
- assert_eq!(map.find(&3).unwrap(), &10);
- assert_eq!(map.find(&5).unwrap(), &3);
- assert_eq!(map.find(&9).unwrap(), &1);
-
- // sadly, no sevens were counted
- assert!(map.find(&7).is_none());
- }
-
- #[test]
- fn test_swap() {
- let mut m = SmallIntMap::new();
- assert_eq!(m.swap(1, 2i), None);
- assert_eq!(m.swap(1, 3i), Some(2));
- assert_eq!(m.swap(1, 4i), Some(3));
- }
-
- #[test]
- fn test_pop() {
- let mut m = SmallIntMap::new();
- m.insert(1, 2i);
- assert_eq!(m.pop(&1), Some(2));
- assert_eq!(m.pop(&1), None);
- }
-
- #[test]
- fn test_keys() {
- let mut map = SmallIntMap::new();
- map.insert(1, 'a');
- map.insert(2, 'b');
- map.insert(3, 'c');
- let keys = map.keys().collect::<Vec<uint>>();
- assert_eq!(keys.len(), 3);
- assert!(keys.contains(&1));
- assert!(keys.contains(&2));
- assert!(keys.contains(&3));
- }
-
- #[test]
- fn test_values() {
- let mut map = SmallIntMap::new();
- map.insert(1, 'a');
- map.insert(2, 'b');
- map.insert(3, 'c');
- let values = map.values().map(|&v| v).collect::<Vec<char>>();
- assert_eq!(values.len(), 3);
- assert!(values.contains(&'a'));
- assert!(values.contains(&'b'));
- assert!(values.contains(&'c'));
- }
-
- #[test]
- fn test_iterator() {
- let mut m = SmallIntMap::new();
-
- assert!(m.insert(0, 1i));
- assert!(m.insert(1, 2));
- assert!(m.insert(3, 5));
- assert!(m.insert(6, 10));
- assert!(m.insert(10, 11));
-
- let mut it = m.iter();
- assert_eq!(it.size_hint(), (0, Some(11)));
- assert_eq!(it.next().unwrap(), (0, &1));
- assert_eq!(it.size_hint(), (0, Some(10)));
- assert_eq!(it.next().unwrap(), (1, &2));
- assert_eq!(it.size_hint(), (0, Some(9)));
- assert_eq!(it.next().unwrap(), (3, &5));
- assert_eq!(it.size_hint(), (0, Some(7)));
- assert_eq!(it.next().unwrap(), (6, &10));
- assert_eq!(it.size_hint(), (0, Some(4)));
- assert_eq!(it.next().unwrap(), (10, &11));
- assert_eq!(it.size_hint(), (0, Some(0)));
- assert!(it.next().is_none());
- }
-
- #[test]
- fn test_iterator_size_hints() {
- let mut m = SmallIntMap::new();
-
- assert!(m.insert(0, 1i));
- assert!(m.insert(1, 2));
- assert!(m.insert(3, 5));
- assert!(m.insert(6, 10));
- assert!(m.insert(10, 11));
-
- assert_eq!(m.iter().size_hint(), (0, Some(11)));
- assert_eq!(m.iter().rev().size_hint(), (0, Some(11)));
- assert_eq!(m.iter_mut().size_hint(), (0, Some(11)));
- assert_eq!(m.iter_mut().rev().size_hint(), (0, Some(11)));
- }
-
- #[test]
- fn test_mut_iterator() {
- let mut m = SmallIntMap::new();
-
- assert!(m.insert(0, 1i));
- assert!(m.insert(1, 2));
- assert!(m.insert(3, 5));
- assert!(m.insert(6, 10));
- assert!(m.insert(10, 11));
-
- for (k, v) in m.iter_mut() {
- *v += k as int;
- }
-
- let mut it = m.iter();
- assert_eq!(it.next().unwrap(), (0, &1));
- assert_eq!(it.next().unwrap(), (1, &3));
- assert_eq!(it.next().unwrap(), (3, &8));
- assert_eq!(it.next().unwrap(), (6, &16));
- assert_eq!(it.next().unwrap(), (10, &21));
- assert!(it.next().is_none());
- }
-
- #[test]
- fn test_rev_iterator() {
- let mut m = SmallIntMap::new();
-
- assert!(m.insert(0, 1i));
- assert!(m.insert(1, 2));
- assert!(m.insert(3, 5));
- assert!(m.insert(6, 10));
- assert!(m.insert(10, 11));
-
- let mut it = m.iter().rev();
- assert_eq!(it.next().unwrap(), (10, &11));
- assert_eq!(it.next().unwrap(), (6, &10));
- assert_eq!(it.next().unwrap(), (3, &5));
- assert_eq!(it.next().unwrap(), (1, &2));
- assert_eq!(it.next().unwrap(), (0, &1));
- assert!(it.next().is_none());
- }
-
- #[test]
- fn test_mut_rev_iterator() {
- let mut m = SmallIntMap::new();
-
- assert!(m.insert(0, 1i));
- assert!(m.insert(1, 2));
- assert!(m.insert(3, 5));
- assert!(m.insert(6, 10));
- assert!(m.insert(10, 11));
-
- for (k, v) in m.iter_mut().rev() {
- *v += k as int;
- }
-
- let mut it = m.iter();
- assert_eq!(it.next().unwrap(), (0, &1));
- assert_eq!(it.next().unwrap(), (1, &3));
- assert_eq!(it.next().unwrap(), (3, &8));
- assert_eq!(it.next().unwrap(), (6, &16));
- assert_eq!(it.next().unwrap(), (10, &21));
- assert!(it.next().is_none());
- }
-
- #[test]
- fn test_move_iter() {
- let mut m = SmallIntMap::new();
- m.insert(1, box 2i);
- let mut called = false;
- for (k, v) in m.into_iter() {
- assert!(!called);
- called = true;
- assert_eq!(k, 1);
- assert_eq!(v, box 2i);
- }
- assert!(called);
- m.insert(2, box 1i);
- }
-
- #[test]
- fn test_show() {
- let mut map = SmallIntMap::new();
- let empty = SmallIntMap::<int>::new();
-
- map.insert(1, 2i);
- map.insert(3, 4i);
-
- let map_str = map.to_string();
- let map_str = map_str.as_slice();
- assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
- assert_eq!(format!("{}", empty), "{}".to_string());
- }
-
- #[test]
- fn test_clone() {
- let mut a = SmallIntMap::new();
-
- a.insert(1, 'x');
- a.insert(4, 'y');
- a.insert(6, 'z');
-
- assert!(a.clone() == a);
- }
-
- #[test]
- fn test_eq() {
- let mut a = SmallIntMap::new();
- let mut b = SmallIntMap::new();
-
- assert!(a == b);
- assert!(a.insert(0, 5i));
- assert!(a != b);
- assert!(b.insert(0, 4i));
- assert!(a != b);
- assert!(a.insert(5, 19));
- assert!(a != b);
- assert!(!b.insert(0, 5));
- assert!(a != b);
- assert!(b.insert(5, 19));
- assert!(a == b);
- }
-
- #[test]
- fn test_lt() {
- let mut a = SmallIntMap::new();
- let mut b = SmallIntMap::new();
-
- assert!(!(a < b) && !(b < a));
- assert!(b.insert(2u, 5i));
- assert!(a < b);
- assert!(a.insert(2, 7));
- assert!(!(a < b) && b < a);
- assert!(b.insert(1, 0));
- assert!(b < a);
- assert!(a.insert(0, 6));
- assert!(a < b);
- assert!(a.insert(6, 2));
- assert!(a < b && !(b < a));
- }
-
- #[test]
- fn test_ord() {
- let mut a = SmallIntMap::new();
- let mut b = SmallIntMap::new();
-
- assert!(a <= b && a >= b);
- assert!(a.insert(1u, 1i));
- assert!(a > b && a >= b);
- assert!(b < a && b <= a);
- assert!(b.insert(2, 2));
- assert!(b > a && b >= a);
- assert!(a < b && a <= b);
- }
-
- #[test]
- fn test_hash() {
- let mut x = SmallIntMap::new();
- let mut y = SmallIntMap::new();
-
- assert!(hash::hash(&x) == hash::hash(&y));
- x.insert(1, 'a');
- x.insert(2, 'b');
- x.insert(3, 'c');
-
- y.insert(3, 'c');
- y.insert(2, 'b');
- y.insert(1, 'a');
-
- assert!(hash::hash(&x) == hash::hash(&y));
- }
-
- #[test]
- fn test_from_iter() {
- let xs: Vec<(uint, char)> = vec![(1u, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')];
-
- let map: SmallIntMap<char> = xs.iter().map(|&x| x).collect();
-
- for &(k, v) in xs.iter() {
- assert_eq!(map.find(&k), Some(&v));
- }
- }
-
- #[test]
- fn test_index() {
- let mut map: SmallIntMap<int> = SmallIntMap::new();
-
- map.insert(1, 2);
- map.insert(2, 1);
- map.insert(3, 4);
-
- assert_eq!(map[3], 4);
- }
-
- #[test]
- #[should_fail]
- fn test_index_nonexistent() {
- let mut map: SmallIntMap<int> = SmallIntMap::new();
-
- map.insert(1, 2);
- map.insert(2, 1);
- map.insert(3, 4);
-
- map[4];
- }
-}
-
-#[cfg(test)]
-mod bench {
- extern crate test;
- use self::test::Bencher;
- use super::SmallIntMap;
- use bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n};
-
- #[bench]
- pub fn insert_rand_100(b: &mut Bencher) {
- let mut m : SmallIntMap<uint> = SmallIntMap::new();
- insert_rand_n(100, &mut m, b,
- |m, i| { m.insert(i, 1); },
- |m, i| { m.remove(&i); });
- }
-
- #[bench]
- pub fn insert_rand_10_000(b: &mut Bencher) {
- let mut m : SmallIntMap<uint> = SmallIntMap::new();
- insert_rand_n(10_000, &mut m, b,
- |m, i| { m.insert(i, 1); },
- |m, i| { m.remove(&i); });
- }
-
- // Insert seq
- #[bench]
- pub fn insert_seq_100(b: &mut Bencher) {
- let mut m : SmallIntMap<uint> = SmallIntMap::new();
- insert_seq_n(100, &mut m, b,
- |m, i| { m.insert(i, 1); },
- |m, i| { m.remove(&i); });
- }
-
- #[bench]
- pub fn insert_seq_10_000(b: &mut Bencher) {
- let mut m : SmallIntMap<uint> = SmallIntMap::new();
- insert_seq_n(10_000, &mut m, b,
- |m, i| { m.insert(i, 1); },
- |m, i| { m.remove(&i); });
- }
-
- // Find rand
- #[bench]
- pub fn find_rand_100(b: &mut Bencher) {
- let mut m : SmallIntMap<uint> = SmallIntMap::new();
- find_rand_n(100, &mut m, b,
- |m, i| { m.insert(i, 1); },
- |m, i| { m.find(&i); });
- }
-
- #[bench]
- pub fn find_rand_10_000(b: &mut Bencher) {
- let mut m : SmallIntMap<uint> = SmallIntMap::new();
- find_rand_n(10_000, &mut m, b,
- |m, i| { m.insert(i, 1); },
- |m, i| { m.find(&i); });
- }
-
- // Find seq
- #[bench]
- pub fn find_seq_100(b: &mut Bencher) {
- let mut m : SmallIntMap<uint> = SmallIntMap::new();
- find_seq_n(100, &mut m, b,
- |m, i| { m.insert(i, 1); },
- |m, i| { m.find(&i); });
- }
-
- #[bench]
- pub fn find_seq_10_000(b: &mut Bencher) {
- let mut m : SmallIntMap<uint> = SmallIntMap::new();
- find_seq_n(10_000, &mut m, b,
- |m, i| { m.insert(i, 1); },
- |m, i| { m.find(&i); });
- }
-}
use core::prelude::{range};
use hash;
-use ringbuf::RingBuf;
+use ring_buf::RingBuf;
use string::String;
use unicode;
use vec::Vec;
--- /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.
+
+use core::prelude::*;
+
+use alloc::boxed::Box;
+use core::default::Default;
+use core::fmt;
+use core::fmt::Show;
+use core::iter;
+use core::mem::{replace, swap};
+use core::ptr;
+use std::hash::{Writer, Hash};
+
+use vec::Vec;
+
+/// This is implemented as an AA tree, which is a simplified variation of
+/// a red-black tree where red (horizontal) nodes can only be added
+/// as a right child. The time complexity is the same, and re-balancing
+/// operations are more frequent but also cheaper.
+///
+/// # Example
+///
+/// ```
+/// use std::collections::TreeMap;
+///
+/// let mut map = TreeMap::new();
+///
+/// map.insert(2i, "bar");
+/// map.insert(1i, "foo");
+/// map.insert(3i, "quux");
+///
+/// // In ascending order by keys
+/// for (key, value) in map.iter() {
+/// println!("{}: {}", key, value);
+/// }
+///
+/// // Prints 1, 2, 3
+/// for key in map.keys() {
+/// println!("{}", key);
+/// }
+///
+/// // Prints `foo`, `bar`, `quux`
+/// for key in map.values() {
+/// println!("{}", key);
+/// }
+///
+/// map.remove(&1);
+/// assert_eq!(map.len(), 2);
+///
+/// if !map.contains_key(&1) {
+/// println!("1 is no more");
+/// }
+///
+/// for key in range(0, 4) {
+/// match map.find(&key) {
+/// Some(val) => println!("{} has a value: {}", key, val),
+/// None => println!("{} not in map", key),
+/// }
+/// }
+///
+/// map.clear();
+/// assert!(map.is_empty());
+/// ```
+///
+/// The easiest way to use `TreeMap` with a custom type as keys is to implement `Ord`.
+/// We must also implement `PartialEq`, `Eq` and `PartialOrd`.
+///
+/// ```
+/// use std::collections::TreeMap;
+///
+/// // We need `Eq` and `PartialEq`, these can be derived.
+/// #[deriving(Eq, PartialEq)]
+/// struct Troll<'a> {
+/// name: &'a str,
+/// level: uint,
+/// }
+///
+/// // Implement `Ord` and sort trolls by level.
+/// impl<'a> Ord for Troll<'a> {
+/// fn cmp(&self, other: &Troll) -> Ordering {
+/// // If we swap `self` and `other`, we get descending ordering.
+/// self.level.cmp(&other.level)
+/// }
+/// }
+///
+/// // `PartialOrd` needs to be implemented as well.
+/// impl<'a> PartialOrd for Troll<'a> {
+/// fn partial_cmp(&self, other: &Troll) -> Option<Ordering> {
+/// Some(self.cmp(other))
+/// }
+/// }
+///
+/// // Use a map to store trolls, sorted by level, and track a list of
+/// // heroes slain.
+/// let mut trolls = TreeMap::new();
+///
+/// trolls.insert(Troll { name: "Orgarr", level: 2 },
+/// vec!["King Karl"]);
+/// trolls.insert(Troll { name: "Blargarr", level: 3 },
+/// vec!["Odd"]);
+/// trolls.insert(Troll { name: "Kron the Smelly One", level: 4 },
+/// vec!["Omar the Brave", "Peter: Slayer of Trolls"]);
+/// trolls.insert(Troll { name: "Wartilda", level: 1 },
+/// vec![]);
+///
+/// println!("You are facing {} trolls!", trolls.len());
+///
+/// // Print the trolls, ordered by level with smallest level first
+/// for (troll, heroes) in trolls.iter() {
+/// let what = if heroes.len() == 1u { "hero" }
+/// else { "heroes" };
+///
+/// println!("level {}: '{}' has slain {} {}",
+/// troll.level, troll.name, heroes.len(), what);
+/// }
+///
+/// // Kill all trolls
+/// trolls.clear();
+/// assert_eq!(trolls.len(), 0);
+/// ```
+
+// Future improvements:
+
+// range search - O(log n) retrieval of an iterator from some key
+
+// (possibly) implement the overloads Python does for sets:
+// * intersection: &
+// * difference: -
+// * symmetric difference: ^
+// * union: |
+// These would be convenient since the methods work like `each`
+
+#[deriving(Clone)]
+pub struct TreeMap<K, V> {
+ root: Option<Box<TreeNode<K, V>>>,
+ length: uint
+}
+
+impl<K: PartialEq + Ord, V: PartialEq> PartialEq for TreeMap<K, V> {
+ fn eq(&self, other: &TreeMap<K, V>) -> bool {
+ self.len() == other.len() &&
+ self.iter().zip(other.iter()).all(|(a, b)| a == b)
+ }
+}
+
+impl<K: Eq + Ord, V: Eq> Eq for TreeMap<K, V> {}
+
+impl<K: Ord, V: PartialOrd> PartialOrd for TreeMap<K, V> {
+ #[inline]
+ fn partial_cmp(&self, other: &TreeMap<K, V>) -> Option<Ordering> {
+ iter::order::partial_cmp(self.iter(), other.iter())
+ }
+}
+
+impl<K: Ord, V: Ord> Ord for TreeMap<K, V> {
+ #[inline]
+ fn cmp(&self, other: &TreeMap<K, V>) -> Ordering {
+ iter::order::cmp(self.iter(), other.iter())
+ }
+}
+
+impl<K: Ord + Show, V: Show> Show for TreeMap<K, V> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ try!(write!(f, "{{"));
+
+ for (i, (k, v)) in self.iter().enumerate() {
+ if i != 0 { try!(write!(f, ", ")); }
+ try!(write!(f, "{}: {}", *k, *v));
+ }
+
+ write!(f, "}}")
+ }
+}
+
+impl<K: Ord, V> Default for TreeMap<K,V> {
+ #[inline]
+ fn default() -> TreeMap<K, V> { TreeMap::new() }
+}
+
+impl<K: Ord, V> Index<K, V> for TreeMap<K, V> {
+ #[inline]
+ fn index<'a>(&'a self, i: &K) -> &'a V {
+ self.find(i).expect("no entry found for key")
+ }
+}
+
+impl<K: Ord, V> IndexMut<K, V> for TreeMap<K, V> {
+ #[inline]
+ fn index_mut<'a>(&'a mut self, i: &K) -> &'a mut V {
+ self.find_mut(i).expect("no entry found for key")
+ }
+}
+
+impl<K: Ord, V> TreeMap<K, V> {
+ /// Creates an empty `TreeMap`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ /// let mut map: TreeMap<&str, int> = TreeMap::new();
+ /// ```
+ pub fn new() -> TreeMap<K, V> { TreeMap{root: None, length: 0} }
+
+ /// Gets a lazy iterator over the keys in the map, in ascending order.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ /// let mut map = TreeMap::new();
+ /// map.insert("a", 1i);
+ /// map.insert("c", 3i);
+ /// map.insert("b", 2i);
+ ///
+ /// // Print "a", "b", "c" in order.
+ /// for x in map.keys() {
+ /// println!("{}", x);
+ /// }
+ /// ```
+ pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
+ self.iter().map(|(k, _v)| k)
+ }
+
+ /// Gets a lazy iterator over the values in the map, in ascending order
+ /// with respect to the corresponding keys.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ /// let mut map = TreeMap::new();
+ /// map.insert("a", 1i);
+ /// map.insert("c", 3i);
+ /// map.insert("b", 2i);
+ ///
+ /// // Print 1, 2, 3 ordered by keys.
+ /// for x in map.values() {
+ /// println!("{}", x);
+ /// }
+ /// ```
+ pub fn values<'a>(&'a self) -> Values<'a, K, V> {
+ self.iter().map(|(_k, v)| v)
+ }
+
+ /// Gets a lazy iterator over the key-value pairs in the map, in ascending order.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ /// let mut map = TreeMap::new();
+ /// map.insert("a", 1i);
+ /// map.insert("c", 3i);
+ /// map.insert("b", 2i);
+ ///
+ /// // Print contents in ascending order
+ /// for (key, value) in map.iter() {
+ /// println!("{}: {}", key, value);
+ /// }
+ /// ```
+ pub fn iter<'a>(&'a self) -> Entries<'a, K, V> {
+ Entries {
+ stack: vec!(),
+ node: deref(&self.root),
+ remaining_min: self.length,
+ remaining_max: self.length
+ }
+ }
+
+ /// Gets a lazy reverse iterator over the key-value pairs in the map, in descending order.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ /// let mut map = TreeMap::new();
+ /// map.insert("a", 1i);
+ /// map.insert("c", 3i);
+ /// map.insert("b", 2i);
+ ///
+ /// // Print contents in descending order
+ /// for (key, value) in map.rev_iter() {
+ /// println!("{}: {}", key, value);
+ /// }
+ /// ```
+ pub fn rev_iter<'a>(&'a self) -> RevEntries<'a, K, V> {
+ RevEntries{iter: self.iter()}
+ }
+
+ /// Gets a lazy forward iterator over the key-value pairs in the
+ /// map, with the values being mutable.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ /// let mut map = TreeMap::new();
+ /// map.insert("a", 1i);
+ /// map.insert("c", 3i);
+ /// map.insert("b", 2i);
+ ///
+ /// // Add 10 until we find "b"
+ /// for (key, value) in map.iter_mut() {
+ /// *value += 10;
+ /// if key == &"b" { break }
+ /// }
+ ///
+ /// assert_eq!(map.find(&"a"), Some(&11));
+ /// assert_eq!(map.find(&"b"), Some(&12));
+ /// assert_eq!(map.find(&"c"), Some(&3));
+ /// ```
+ pub fn iter_mut<'a>(&'a mut self) -> MutEntries<'a, K, V> {
+ MutEntries {
+ stack: vec!(),
+ node: deref_mut(&mut self.root),
+ remaining_min: self.length,
+ remaining_max: self.length
+ }
+ }
+
+ /// Gets a lazy reverse iterator over the key-value pairs in the
+ /// map, with the values being mutable.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ /// let mut map = TreeMap::new();
+ /// map.insert("a", 1i);
+ /// map.insert("c", 3i);
+ /// map.insert("b", 2i);
+ ///
+ /// // Add 10 until we find "b"
+ /// for (key, value) in map.rev_iter_mut() {
+ /// *value += 10;
+ /// if key == &"b" { break }
+ /// }
+ ///
+ /// assert_eq!(map.find(&"a"), Some(&1));
+ /// assert_eq!(map.find(&"b"), Some(&12));
+ /// assert_eq!(map.find(&"c"), Some(&13));
+ /// ```
+ pub fn rev_iter_mut<'a>(&'a mut self) -> RevMutEntries<'a, K, V> {
+ RevMutEntries{iter: self.iter_mut()}
+ }
+
+ /// Gets a lazy iterator that consumes the TreeMap.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ /// let mut map = TreeMap::new();
+ /// map.insert("a", 1i);
+ /// map.insert("c", 3i);
+ /// map.insert("b", 2i);
+ ///
+ /// // Not possible with a regular `.iter()`
+ /// let vec: Vec<(&str, int)> = map.into_iter().collect();
+ /// assert_eq!(vec, vec![("a", 1), ("b", 2), ("c", 3)]);
+ /// ```
+ pub fn into_iter(self) -> MoveEntries<K, V> {
+ let TreeMap { root, length } = self;
+ let stk = match root {
+ None => vec!(),
+ Some(box tn) => vec!(tn)
+ };
+ MoveEntries {
+ stack: stk,
+ remaining: length
+ }
+ }
+
+ /// Return the number of elements in the map.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ ///
+ /// let mut a = TreeMap::new();
+ /// assert_eq!(a.len(), 0);
+ /// a.insert(1u, "a");
+ /// assert_eq!(a.len(), 1);
+ /// ```
+ pub fn len(&self) -> uint { self.length }
+
+ /// Return true if the map contains no elements.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ ///
+ /// let mut a = TreeMap::new();
+ /// assert!(a.is_empty());
+ /// a.insert(1u, "a");
+ /// assert!(!a.is_empty());
+ /// ```
+ #[inline]
+ pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+ /// Clears the map, removing all values.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ ///
+ /// let mut a = TreeMap::new();
+ /// a.insert(1u, "a");
+ /// a.clear();
+ /// assert!(a.is_empty());
+ /// ```
+ pub fn clear(&mut self) {
+ self.root = None;
+ self.length = 0
+ }
+
+ /// Returns a reference to the value corresponding to the key.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ ///
+ /// let mut map = TreeMap::new();
+ /// map.insert(1u, "a");
+ /// assert_eq!(map.find(&1), Some(&"a"));
+ /// assert_eq!(map.find(&2), None);
+ /// ```
+ #[inline]
+ pub fn find<'a>(&'a self, key: &K) -> Option<&'a V> {
+ tree_find_with(&self.root, |k2| key.cmp(k2))
+ }
+
+ /// Returns true if the map contains a value for the specified key.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ ///
+ /// let mut map = TreeMap::new();
+ /// map.insert(1u, "a");
+ /// assert_eq!(map.contains_key(&1), true);
+ /// assert_eq!(map.contains_key(&2), false);
+ /// ```
+ #[inline]
+ pub fn contains_key(&self, key: &K) -> bool {
+ self.find(key).is_some()
+ }
+
+ /// Returns a mutable reference to the value corresponding to the key.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ ///
+ /// let mut map = TreeMap::new();
+ /// map.insert(1u, "a");
+ /// match map.find_mut(&1) {
+ /// Some(x) => *x = "b",
+ /// None => (),
+ /// }
+ /// assert_eq!(map[1], "b");
+ /// ```
+ #[inline]
+ pub fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> {
+ tree_find_with_mut(&mut self.root, |x| key.cmp(x))
+ }
+
+ /// Inserts a key-value pair into the map. An existing value for a
+ /// key is replaced by the new value. Returns `true` if the key did
+ /// not already exist in the map.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ ///
+ /// let mut map = TreeMap::new();
+ /// assert_eq!(map.insert(2u, "value"), true);
+ /// assert_eq!(map.insert(2, "value2"), false);
+ /// assert_eq!(map[2], "value2");
+ /// ```
+ #[inline]
+ pub fn insert(&mut self, key: K, value: V) -> bool {
+ self.swap(key, value).is_none()
+ }
+
+ /// Removes a key-value pair from the map. Returns `true` if the key
+ /// was present in the map.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ ///
+ /// let mut map = TreeMap::new();
+ /// assert_eq!(map.remove(&1u), false);
+ /// map.insert(1, "a");
+ /// assert_eq!(map.remove(&1), true);
+ /// ```
+ #[inline]
+ pub fn remove(&mut self, key: &K) -> bool {
+ self.pop(key).is_some()
+ }
+
+ /// Inserts a key-value pair from the map. If the key already had a value
+ /// present in the map, that value is returned. Otherwise, `None` is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ ///
+ /// let mut map = TreeMap::new();
+ /// assert_eq!(map.swap(37u, "a"), None);
+ /// assert_eq!(map.is_empty(), false);
+ ///
+ /// map.insert(37, "b");
+ /// assert_eq!(map.swap(37, "c"), Some("b"));
+ /// assert_eq!(map[37], "c");
+ /// ```
+ pub fn swap(&mut self, key: K, value: V) -> Option<V> {
+ let ret = insert(&mut self.root, key, value);
+ 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.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ ///
+ /// let mut map = TreeMap::new();
+ /// map.insert(1u, "a");
+ /// assert_eq!(map.pop(&1), Some("a"));
+ /// assert_eq!(map.pop(&1), None);
+ /// ```
+ pub fn pop(&mut self, key: &K) -> Option<V> {
+ let ret = remove(&mut self.root, key);
+ if ret.is_some() { self.length -= 1 }
+ ret
+ }
+}
+
+impl<K, V> TreeMap<K, V> {
+ /// Returns the value for which `f(key)` returns `Equal`. `f` is invoked
+ /// with current key and guides tree navigation. That means `f` should
+ /// be aware of natural ordering of the tree.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ ///
+ /// fn get_headers() -> TreeMap<String, String> {
+ /// let mut result = TreeMap::new();
+ /// result.insert("Content-Type".to_string(), "application/xml".to_string());
+ /// result.insert("User-Agent".to_string(), "Curl-Rust/0.1".to_string());
+ /// result
+ /// }
+ ///
+ /// let headers = get_headers();
+ /// let ua_key = "User-Agent";
+ /// let ua = headers.find_with(|k| {
+ /// ua_key.cmp(&k.as_slice())
+ /// });
+ ///
+ /// assert_eq!((*ua.unwrap()).as_slice(), "Curl-Rust/0.1");
+ /// ```
+ #[inline]
+ pub fn find_with<'a>(&'a self, f:|&K| -> Ordering) -> Option<&'a V> {
+ tree_find_with(&self.root, f)
+ }
+
+ /// Returns the value for which `f(key)` returns `Equal`. `f` is invoked
+ /// with current key and guides tree navigation. That means `f` should
+ /// be aware of natural ordering of the tree.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ ///
+ /// let mut t = TreeMap::new();
+ /// t.insert("Content-Type", "application/xml");
+ /// t.insert("User-Agent", "Curl-Rust/0.1");
+ ///
+ /// let new_ua = "Safari/156.0";
+ /// match t.find_with_mut(|k| "User-Agent".cmp(k)) {
+ /// Some(x) => *x = new_ua,
+ /// None => panic!(),
+ /// }
+ ///
+ /// assert_eq!(t.find(&"User-Agent"), Some(&new_ua));
+ /// ```
+ #[inline]
+ pub fn find_with_mut<'a>(&'a mut self, f:|&K| -> Ordering) -> Option<&'a mut V> {
+ tree_find_with_mut(&mut self.root, f)
+ }
+}
+
+// range iterators.
+
+macro_rules! bound_setup {
+ // initialiser of the iterator to manipulate
+ ($iter:expr, $k:expr,
+ // whether we are looking for the lower or upper bound.
+ $is_lower_bound:expr) => {
+ {
+ let mut iter = $iter;
+ loop {
+ if !iter.node.is_null() {
+ let node_k = unsafe {&(*iter.node).key};
+ match $k.cmp(node_k) {
+ Less => iter.traverse_left(),
+ Greater => iter.traverse_right(),
+ Equal => {
+ if $is_lower_bound {
+ iter.traverse_complete();
+ return iter;
+ } else {
+ iter.traverse_right()
+ }
+ }
+ }
+ } else {
+ iter.traverse_complete();
+ return iter;
+ }
+ }
+ }
+ }
+}
+
+
+impl<K: Ord, V> TreeMap<K, V> {
+ /// Gets a lazy iterator that should be initialized using
+ /// `traverse_left`/`traverse_right`/`traverse_complete`.
+ fn iter_for_traversal<'a>(&'a self) -> Entries<'a, K, V> {
+ Entries {
+ stack: vec!(),
+ node: deref(&self.root),
+ remaining_min: 0,
+ remaining_max: self.length
+ }
+ }
+
+ /// Returns a lazy iterator to the first key-value pair whose key is not less than `k`
+ /// If all keys in map are less than `k` an empty iterator is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ ///
+ /// let mut map = TreeMap::new();
+ /// map.insert(2i, "a");
+ /// map.insert(4, "b");
+ /// map.insert(6, "c");
+ /// map.insert(8, "d");
+ ///
+ /// assert_eq!(map.lower_bound(&4).next(), Some((&4, &"b")));
+ /// assert_eq!(map.lower_bound(&5).next(), Some((&6, &"c")));
+ /// assert_eq!(map.lower_bound(&10).next(), None);
+ /// ```
+ pub fn lower_bound<'a>(&'a self, k: &K) -> Entries<'a, K, V> {
+ bound_setup!(self.iter_for_traversal(), k, true)
+ }
+
+ /// Returns a lazy iterator to the first key-value pair whose key is greater than `k`
+ /// If all keys in map are less than or equal to `k` an empty iterator is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ ///
+ /// let mut map = TreeMap::new();
+ /// map.insert(2i, "a");
+ /// map.insert(4, "b");
+ /// map.insert(6, "c");
+ /// map.insert(8, "d");
+ ///
+ /// assert_eq!(map.upper_bound(&4).next(), Some((&6, &"c")));
+ /// assert_eq!(map.upper_bound(&5).next(), Some((&6, &"c")));
+ /// assert_eq!(map.upper_bound(&10).next(), None);
+ /// ```
+ pub fn upper_bound<'a>(&'a self, k: &K) -> Entries<'a, K, V> {
+ bound_setup!(self.iter_for_traversal(), k, false)
+ }
+
+ /// Gets a lazy iterator that should be initialized using
+ /// `traverse_left`/`traverse_right`/`traverse_complete`.
+ fn iter_mut_for_traversal<'a>(&'a mut self) -> MutEntries<'a, K, V> {
+ MutEntries {
+ stack: vec!(),
+ node: deref_mut(&mut self.root),
+ remaining_min: 0,
+ remaining_max: self.length
+ }
+ }
+
+ /// Returns a lazy value iterator to the first key-value pair (with
+ /// the value being mutable) whose key is not less than `k`.
+ ///
+ /// If all keys in map are less than `k` an empty iterator is
+ /// returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ ///
+ /// let mut map = TreeMap::new();
+ /// map.insert(2i, "a");
+ /// map.insert(4, "b");
+ /// map.insert(6, "c");
+ /// map.insert(8, "d");
+ ///
+ /// assert_eq!(map.lower_bound_mut(&4).next(), Some((&4, &mut "b")));
+ /// assert_eq!(map.lower_bound_mut(&5).next(), Some((&6, &mut "c")));
+ /// assert_eq!(map.lower_bound_mut(&10).next(), None);
+ ///
+ /// for (key, value) in map.lower_bound_mut(&4) {
+ /// *value = "changed";
+ /// }
+ ///
+ /// assert_eq!(map.find(&2), Some(&"a"));
+ /// assert_eq!(map.find(&4), Some(&"changed"));
+ /// assert_eq!(map.find(&6), Some(&"changed"));
+ /// assert_eq!(map.find(&8), Some(&"changed"));
+ /// ```
+ pub fn lower_bound_mut<'a>(&'a mut self, k: &K) -> MutEntries<'a, K, V> {
+ bound_setup!(self.iter_mut_for_traversal(), k, true)
+ }
+
+ /// Returns a lazy iterator to the first key-value pair (with the
+ /// value being mutable) whose key is greater than `k`.
+ ///
+ /// If all keys in map are less than or equal to `k` an empty iterator
+ /// is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeMap;
+ ///
+ /// let mut map = TreeMap::new();
+ /// map.insert(2i, "a");
+ /// map.insert(4, "b");
+ /// map.insert(6, "c");
+ /// map.insert(8, "d");
+ ///
+ /// assert_eq!(map.upper_bound_mut(&4).next(), Some((&6, &mut "c")));
+ /// assert_eq!(map.upper_bound_mut(&5).next(), Some((&6, &mut "c")));
+ /// assert_eq!(map.upper_bound_mut(&10).next(), None);
+ ///
+ /// for (key, value) in map.upper_bound_mut(&4) {
+ /// *value = "changed";
+ /// }
+ ///
+ /// assert_eq!(map.find(&2), Some(&"a"));
+ /// assert_eq!(map.find(&4), Some(&"b"));
+ /// assert_eq!(map.find(&6), Some(&"changed"));
+ /// assert_eq!(map.find(&8), Some(&"changed"));
+ /// ```
+ pub fn upper_bound_mut<'a>(&'a mut self, k: &K) -> MutEntries<'a, K, V> {
+ bound_setup!(self.iter_mut_for_traversal(), k, false)
+ }
+}
+
+/// Lazy forward iterator over a map
+pub struct Entries<'a, K:'a, V:'a> {
+ stack: Vec<&'a TreeNode<K, V>>,
+ // See the comment on MutEntries; this is just to allow
+ // code-sharing (for this immutable-values iterator it *could* very
+ // well be Option<&'a TreeNode<K,V>>).
+ node: *const TreeNode<K, V>,
+ remaining_min: uint,
+ remaining_max: uint
+}
+
+/// Lazy backward iterator over a map
+pub struct RevEntries<'a, K:'a, V:'a> {
+ iter: Entries<'a, K, V>,
+}
+
+/// Lazy forward iterator over a map that allows for the mutation of
+/// the values.
+pub struct MutEntries<'a, K:'a, V:'a> {
+ stack: Vec<&'a mut TreeNode<K, V>>,
+ // Unfortunately, we require some unsafe-ness to get around the
+ // fact that we would be storing a reference *into* one of the
+ // nodes in the stack.
+ //
+ // As far as the compiler knows, this would let us invalidate the
+ // reference by assigning a new value to this node's position in
+ // its parent, which would cause this current one to be
+ // deallocated so this reference would be invalid. (i.e. the
+ // compilers complaints are 100% correct.)
+ //
+ // However, as far as you humans reading this code know (or are
+ // about to know, if you haven't read far enough down yet), we are
+ // only reading from the TreeNode.{left,right} fields. the only
+ // thing that is ever mutated is the .value field (although any
+ // actual mutation that happens is done externally, by the
+ // iterator consumer). So, don't be so concerned, rustc, we've got
+ // it under control.
+ //
+ // (This field can legitimately be null.)
+ node: *mut TreeNode<K, V>,
+ remaining_min: uint,
+ remaining_max: uint
+}
+
+/// Lazy backward iterator over a map
+pub struct RevMutEntries<'a, K:'a, V:'a> {
+ iter: MutEntries<'a, K, V>,
+}
+
+/// TreeMap keys iterator.
+pub type Keys<'a, K, V> =
+ iter::Map<'static, (&'a K, &'a V), &'a K, Entries<'a, K, V>>;
+
+/// TreeMap values iterator.
+pub type Values<'a, K, V> =
+ iter::Map<'static, (&'a K, &'a V), &'a V, Entries<'a, K, V>>;
+
+
+// FIXME #5846 we want to be able to choose between &x and &mut x
+// (with many different `x`) below, so we need to optionally pass mut
+// as a tt, but the only thing we can do with a `tt` is pass them to
+// other macros, so this takes the `& <mutability> <operand>` token
+// sequence and forces their evaluation as an expression.
+macro_rules! addr { ($e:expr) => { $e }}
+// putting an optional mut into type signatures
+macro_rules! item { ($i:item) => { $i }}
+
+macro_rules! define_iterator {
+ ($name:ident,
+ $rev_name:ident,
+
+ // the function to go from &m Option<Box<TreeNode>> to *m TreeNode
+ deref = $deref:ident,
+
+ // see comment on `addr!`, this is just an optional `mut`, but
+ // there's no support for 0-or-1 repeats.
+ addr_mut = $($addr_mut:tt)*
+ ) => {
+ // private methods on the forward iterator (item!() for the
+ // addr_mut in the next_ return value)
+ item!(impl<'a, K, V> $name<'a, K, V> {
+ #[inline(always)]
+ fn next_(&mut self, forward: bool) -> Option<(&'a K, &'a $($addr_mut)* V)> {
+ while !self.stack.is_empty() || !self.node.is_null() {
+ if !self.node.is_null() {
+ let node = unsafe {addr!(& $($addr_mut)* *self.node)};
+ {
+ let next_node = if forward {
+ addr!(& $($addr_mut)* node.left)
+ } else {
+ addr!(& $($addr_mut)* node.right)
+ };
+ self.node = $deref(next_node);
+ }
+ self.stack.push(node);
+ } else {
+ let node = self.stack.pop().unwrap();
+ let next_node = if forward {
+ addr!(& $($addr_mut)* node.right)
+ } else {
+ addr!(& $($addr_mut)* node.left)
+ };
+ self.node = $deref(next_node);
+ self.remaining_max -= 1;
+ if self.remaining_min > 0 {
+ self.remaining_min -= 1;
+ }
+ return Some((&node.key, addr!(& $($addr_mut)* node.value)));
+ }
+ }
+ None
+ }
+
+ /// traverse_left, traverse_right and traverse_complete are
+ /// used to initialize Entries/MutEntries
+ /// pointing to element inside tree structure.
+ ///
+ /// They should be used in following manner:
+ /// - create iterator using TreeMap::[mut_]iter_for_traversal
+ /// - find required node using `traverse_left`/`traverse_right`
+ /// (current node is `Entries::node` field)
+ /// - complete initialization with `traverse_complete`
+ ///
+ /// After this, iteration will start from `self.node`. If
+ /// `self.node` is None iteration will start from last
+ /// node from which we traversed left.
+ #[inline]
+ fn traverse_left(&mut self) {
+ let node = unsafe {addr!(& $($addr_mut)* *self.node)};
+ self.node = $deref(addr!(& $($addr_mut)* node.left));
+ self.stack.push(node);
+ }
+
+ #[inline]
+ fn traverse_right(&mut self) {
+ let node = unsafe {addr!(& $($addr_mut)* *self.node)};
+ self.node = $deref(addr!(& $($addr_mut)* node.right));
+ }
+
+ #[inline]
+ fn traverse_complete(&mut self) {
+ if !self.node.is_null() {
+ unsafe {
+ self.stack.push(addr!(& $($addr_mut)* *self.node));
+ }
+ self.node = ptr::RawPtr::null();
+ }
+ }
+ })
+
+ // the forward Iterator impl.
+ item!(impl<'a, K, V> Iterator<(&'a K, &'a $($addr_mut)* V)> for $name<'a, K, V> {
+ /// Advances the iterator to the next node (in order) and return a
+ /// tuple with a reference to the key and value. If there are no
+ /// more nodes, return `None`.
+ fn next(&mut self) -> Option<(&'a K, &'a $($addr_mut)* V)> {
+ self.next_(true)
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ (self.remaining_min, Some(self.remaining_max))
+ }
+ })
+
+ // the reverse Iterator impl.
+ item!(impl<'a, K, V> Iterator<(&'a K, &'a $($addr_mut)* V)> for $rev_name<'a, K, V> {
+ fn next(&mut self) -> Option<(&'a K, &'a $($addr_mut)* V)> {
+ self.iter.next_(false)
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ self.iter.size_hint()
+ }
+ })
+ }
+} // end of define_iterator
+
+define_iterator! {
+ Entries,
+ RevEntries,
+ deref = deref,
+
+ // immutable, so no mut
+ addr_mut =
+}
+define_iterator! {
+ MutEntries,
+ RevMutEntries,
+ deref = deref_mut,
+
+ addr_mut = mut
+}
+
+fn deref<'a, K, V>(node: &'a Option<Box<TreeNode<K, V>>>) -> *const TreeNode<K, V> {
+ match *node {
+ Some(ref n) => {
+ let n: &TreeNode<K, V> = &**n;
+ n as *const TreeNode<K, V>
+ }
+ None => ptr::null()
+ }
+}
+
+fn deref_mut<K, V>(x: &mut Option<Box<TreeNode<K, V>>>)
+ -> *mut TreeNode<K, V> {
+ match *x {
+ Some(ref mut n) => {
+ let n: &mut TreeNode<K, V> = &mut **n;
+ n as *mut TreeNode<K, V>
+ }
+ None => ptr::null_mut()
+ }
+}
+
+/// Lazy forward iterator over a map that consumes the map while iterating
+pub struct MoveEntries<K, V> {
+ stack: Vec<TreeNode<K, V>>,
+ remaining: uint
+}
+
+impl<K, V> Iterator<(K, V)> for MoveEntries<K,V> {
+ #[inline]
+ fn next(&mut self) -> Option<(K, V)> {
+ while !self.stack.is_empty() {
+ let TreeNode {
+ key,
+ value,
+ left,
+ right,
+ level,
+ } = self.stack.pop().unwrap();
+
+ match left {
+ Some(box left) => {
+ let n = TreeNode {
+ key: key,
+ value: value,
+ left: None,
+ right: right,
+ level: level
+ };
+ self.stack.push(n);
+ self.stack.push(left);
+ }
+ None => {
+ match right {
+ Some(box right) => self.stack.push(right),
+ None => ()
+ }
+ self.remaining -= 1;
+ return Some((key, value))
+ }
+ }
+ }
+ None
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ (self.remaining, Some(self.remaining))
+ }
+
+}
+
+
+
+// Nodes keep track of their level in the tree, starting at 1 in the
+// leaves and with a red child sharing the level of the parent.
+#[deriving(Clone)]
+struct TreeNode<K, V> {
+ key: K,
+ value: V,
+ left: Option<Box<TreeNode<K, V>>>,
+ right: Option<Box<TreeNode<K, V>>>,
+ level: uint
+}
+
+impl<K: Ord, V> TreeNode<K, V> {
+ /// Creates a new tree node.
+ #[inline]
+ pub fn new(key: K, value: V) -> TreeNode<K, V> {
+ TreeNode{key: key, value: value, left: None, right: None, level: 1}
+ }
+}
+
+// Remove left horizontal link by rotating right
+fn skew<K: Ord, V>(node: &mut Box<TreeNode<K, V>>) {
+ if node.left.as_ref().map_or(false, |x| x.level == node.level) {
+ let mut save = node.left.take().unwrap();
+ swap(&mut node.left, &mut save.right); // save.right now None
+ swap(node, &mut save);
+ node.right = Some(save);
+ }
+}
+
+// Remove dual horizontal link by rotating left and increasing level of
+// the parent
+fn split<K: Ord, V>(node: &mut Box<TreeNode<K, V>>) {
+ if node.right.as_ref().map_or(false,
+ |x| x.right.as_ref().map_or(false, |y| y.level == node.level)) {
+ let mut save = node.right.take().unwrap();
+ swap(&mut node.right, &mut save.left); // save.left now None
+ save.level += 1;
+ swap(node, &mut save);
+ node.left = Some(save);
+ }
+}
+
+// Next 2 functions have the same convention: comparator gets
+// at input current key and returns search_key cmp cur_key
+// (i.e. search_key.cmp(&cur_key))
+fn tree_find_with<'r, K, V>(node: &'r Option<Box<TreeNode<K, V>>>,
+ f: |&K| -> Ordering) -> Option<&'r V> {
+ let mut current: &'r Option<Box<TreeNode<K, V>>> = node;
+ loop {
+ match *current {
+ Some(ref r) => {
+ match f(&r.key) {
+ Less => current = &r.left,
+ Greater => current = &r.right,
+ Equal => return Some(&r.value)
+ }
+ }
+ None => return None
+ }
+ }
+}
+
+// See comments above tree_find_with
+fn tree_find_with_mut<'r, K, V>(node: &'r mut Option<Box<TreeNode<K, V>>>,
+ f: |&K| -> Ordering) -> Option<&'r mut V> {
+
+ let mut current = node;
+ loop {
+ let temp = current; // hack to appease borrowck
+ match *temp {
+ Some(ref mut r) => {
+ match f(&r.key) {
+ Less => current = &mut r.left,
+ Greater => current = &mut r.right,
+ Equal => return Some(&mut r.value)
+ }
+ }
+ None => return None
+ }
+ }
+}
+
+fn insert<K: Ord, V>(node: &mut Option<Box<TreeNode<K, V>>>,
+ key: K, value: V) -> Option<V> {
+ match *node {
+ Some(ref mut save) => {
+ match key.cmp(&save.key) {
+ Less => {
+ let inserted = insert(&mut save.left, key, value);
+ skew(save);
+ split(save);
+ inserted
+ }
+ Greater => {
+ let inserted = insert(&mut save.right, key, value);
+ skew(save);
+ split(save);
+ inserted
+ }
+ Equal => {
+ save.key = key;
+ Some(replace(&mut save.value, value))
+ }
+ }
+ }
+ None => {
+ *node = Some(box TreeNode::new(key, value));
+ None
+ }
+ }
+}
+
+fn remove<K: Ord, V>(node: &mut Option<Box<TreeNode<K, V>>>,
+ key: &K) -> Option<V> {
+ fn heir_swap<K: Ord, V>(node: &mut Box<TreeNode<K, V>>,
+ child: &mut Option<Box<TreeNode<K, V>>>) {
+ // *could* be done without recursion, but it won't borrow check
+ for x in child.iter_mut() {
+ if x.right.is_some() {
+ heir_swap(node, &mut x.right);
+ } else {
+ swap(&mut node.key, &mut x.key);
+ swap(&mut node.value, &mut x.value);
+ }
+ }
+ }
+
+ match *node {
+ None => {
+ return None; // bottom of tree
+ }
+ Some(ref mut save) => {
+ let (ret, rebalance) = match key.cmp(&save.key) {
+ Less => (remove(&mut save.left, key), true),
+ Greater => (remove(&mut save.right, key), true),
+ Equal => {
+ if save.left.is_some() {
+ if save.right.is_some() {
+ let mut left = save.left.take().unwrap();
+ if left.right.is_some() {
+ heir_swap(save, &mut left.right);
+ } else {
+ swap(&mut save.key, &mut left.key);
+ swap(&mut save.value, &mut left.value);
+ }
+ save.left = Some(left);
+ (remove(&mut save.left, key), true)
+ } else {
+ let new = save.left.take().unwrap();
+ let box TreeNode{value, ..} = replace(save, new);
+ *save = save.left.take().unwrap();
+ (Some(value), true)
+ }
+ } else if save.right.is_some() {
+ let new = save.right.take().unwrap();
+ let box TreeNode{value, ..} = replace(save, new);
+ (Some(value), true)
+ } else {
+ (None, false)
+ }
+ }
+ };
+
+ if rebalance {
+ let left_level = save.left.as_ref().map_or(0, |x| x.level);
+ let right_level = save.right.as_ref().map_or(0, |x| x.level);
+
+ // re-balance, if necessary
+ if left_level < save.level - 1 || right_level < save.level - 1 {
+ save.level -= 1;
+
+ if right_level > save.level {
+ let save_level = save.level;
+ for x in save.right.iter_mut() { x.level = save_level }
+ }
+
+ skew(save);
+
+ for right in save.right.iter_mut() {
+ skew(right);
+ for x in right.right.iter_mut() { skew(x) }
+ }
+
+ split(save);
+ for x in save.right.iter_mut() { split(x) }
+ }
+
+ return ret;
+ }
+ }
+ }
+ return match node.take() {
+ Some(box TreeNode{value, ..}) => Some(value), None => panic!()
+ };
+}
+
+impl<K: Ord, V> FromIterator<(K, V)> for TreeMap<K, V> {
+ fn from_iter<T: Iterator<(K, V)>>(iter: T) -> TreeMap<K, V> {
+ let mut map = TreeMap::new();
+ map.extend(iter);
+ map
+ }
+}
+
+impl<K: Ord, V> Extendable<(K, V)> for TreeMap<K, V> {
+ #[inline]
+ fn extend<T: Iterator<(K, V)>>(&mut self, mut iter: T) {
+ for (k, v) in iter {
+ self.insert(k, v);
+ }
+ }
+}
+
+impl<S: Writer, K: Ord + Hash<S>, V: Hash<S>> Hash<S> for TreeMap<K, V> {
+ fn hash(&self, state: &mut S) {
+ for elt in self.iter() {
+ elt.hash(state);
+ }
+ }
+}
+
+
+#[cfg(test)]
+mod test_treemap {
+ use std::prelude::*;
+ use std::rand::Rng;
+ use std::rand;
+
+ use super::{TreeMap, TreeNode};
+
+ #[test]
+ fn find_empty() {
+ let m: TreeMap<int,int> = TreeMap::new();
+ assert!(m.find(&5) == None);
+ }
+
+ #[test]
+ fn find_not_found() {
+ let mut m = TreeMap::new();
+ assert!(m.insert(1i, 2i));
+ assert!(m.insert(5i, 3i));
+ assert!(m.insert(9i, 3i));
+ assert_eq!(m.find(&2), None);
+ }
+
+ #[test]
+ fn find_with_empty() {
+ let m: TreeMap<&'static str,int> = TreeMap::new();
+ assert!(m.find_with(|k| "test".cmp(k)) == None);
+ }
+
+ #[test]
+ fn find_with_not_found() {
+ let mut m = TreeMap::new();
+ assert!(m.insert("test1", 2i));
+ assert!(m.insert("test2", 3i));
+ assert!(m.insert("test3", 3i));
+ assert_eq!(m.find_with(|k| "test4".cmp(k)), None);
+ }
+
+ #[test]
+ fn find_with_found() {
+ let mut m = TreeMap::new();
+ assert!(m.insert("test1", 2i));
+ assert!(m.insert("test2", 3i));
+ assert!(m.insert("test3", 4i));
+ assert_eq!(m.find_with(|k| "test2".cmp(k)), Some(&3i));
+ }
+
+ #[test]
+ fn test_find_mut() {
+ let mut m = TreeMap::new();
+ assert!(m.insert(1i, 12i));
+ assert!(m.insert(2, 8));
+ assert!(m.insert(5, 14));
+ let new = 100;
+ match m.find_mut(&5) {
+ None => panic!(), Some(x) => *x = new
+ }
+ assert_eq!(m.find(&5), Some(&new));
+ }
+
+ #[test]
+ fn test_find_with_mut() {
+ let mut m = TreeMap::new();
+ assert!(m.insert("t1", 12i));
+ assert!(m.insert("t2", 8));
+ assert!(m.insert("t5", 14));
+ let new = 100;
+ match m.find_with_mut(|k| "t5".cmp(k)) {
+ None => panic!(), Some(x) => *x = new
+ }
+ assert_eq!(m.find_with(|k| "t5".cmp(k)), Some(&new));
+ }
+
+ #[test]
+ fn insert_replace() {
+ let mut m = TreeMap::new();
+ assert!(m.insert(5i, 2i));
+ assert!(m.insert(2, 9));
+ assert!(!m.insert(2, 11));
+ assert_eq!(m.find(&2).unwrap(), &11);
+ }
+
+ #[test]
+ fn test_clear() {
+ let mut m = TreeMap::new();
+ m.clear();
+ assert!(m.insert(5i, 11i));
+ assert!(m.insert(12, -3));
+ assert!(m.insert(19, 2));
+ m.clear();
+ assert!(m.find(&5).is_none());
+ assert!(m.find(&12).is_none());
+ assert!(m.find(&19).is_none());
+ assert!(m.is_empty());
+ }
+
+ #[test]
+ fn u8_map() {
+ let mut m = TreeMap::new();
+
+ let k1 = "foo".as_bytes();
+ let k2 = "bar".as_bytes();
+ let v1 = "baz".as_bytes();
+ let v2 = "foobar".as_bytes();
+
+ m.insert(k1.clone(), v1.clone());
+ m.insert(k2.clone(), v2.clone());
+
+ assert_eq!(m.find(&k2), Some(&v2));
+ assert_eq!(m.find(&k1), Some(&v1));
+ }
+
+ fn check_equal<K: PartialEq + Ord, V: PartialEq>(ctrl: &[(K, V)],
+ map: &TreeMap<K, V>) {
+ assert_eq!(ctrl.is_empty(), map.is_empty());
+ for x in ctrl.iter() {
+ let &(ref k, ref v) = x;
+ assert!(map.find(k).unwrap() == v)
+ }
+ for (map_k, map_v) in map.iter() {
+ let mut found = false;
+ for x in ctrl.iter() {
+ let &(ref ctrl_k, ref ctrl_v) = x;
+ if *map_k == *ctrl_k {
+ assert!(*map_v == *ctrl_v);
+ found = true;
+ break;
+ }
+ }
+ assert!(found);
+ }
+ }
+
+ fn check_left<K: Ord, V>(node: &Option<Box<TreeNode<K, V>>>,
+ parent: &Box<TreeNode<K, V>>) {
+ match *node {
+ Some(ref r) => {
+ assert_eq!(r.key.cmp(&parent.key), Less);
+ assert!(r.level == parent.level - 1); // left is black
+ check_left(&r.left, r);
+ check_right(&r.right, r, false);
+ }
+ None => assert!(parent.level == 1) // parent is leaf
+ }
+ }
+
+ fn check_right<K: Ord, V>(node: &Option<Box<TreeNode<K, V>>>,
+ parent: &Box<TreeNode<K, V>>,
+ parent_red: bool) {
+ match *node {
+ Some(ref r) => {
+ assert_eq!(r.key.cmp(&parent.key), Greater);
+ let red = r.level == parent.level;
+ if parent_red { assert!(!red) } // no dual horizontal links
+ // Right red or black
+ assert!(red || r.level == parent.level - 1);
+ check_left(&r.left, r);
+ check_right(&r.right, r, red);
+ }
+ None => assert!(parent.level == 1) // parent is leaf
+ }
+ }
+
+ fn check_structure<K: Ord, V>(map: &TreeMap<K, V>) {
+ match map.root {
+ Some(ref r) => {
+ check_left(&r.left, r);
+ check_right(&r.right, r, false);
+ }
+ None => ()
+ }
+ }
+
+ #[test]
+ fn test_rand_int() {
+ let mut map: TreeMap<int,int> = TreeMap::new();
+ let mut ctrl = vec![];
+
+ check_equal(ctrl.as_slice(), &map);
+ assert!(map.find(&5).is_none());
+
+ let seed: &[_] = &[42];
+ let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed);
+
+ for _ in range(0u, 3) {
+ for _ in range(0u, 90) {
+ let k = rng.gen();
+ let v = rng.gen();
+ if !ctrl.iter().any(|x| x == &(k, v)) {
+ assert!(map.insert(k, v));
+ ctrl.push((k, v));
+ check_structure(&map);
+ check_equal(ctrl.as_slice(), &map);
+ }
+ }
+
+ for _ in range(0u, 30) {
+ let r = rng.gen_range(0, ctrl.len());
+ let (key, _) = ctrl.remove(r).unwrap();
+ assert!(map.remove(&key));
+ check_structure(&map);
+ check_equal(ctrl.as_slice(), &map);
+ }
+ }
+ }
+
+ #[test]
+ fn test_len() {
+ let mut m = TreeMap::new();
+ assert!(m.insert(3i, 6i));
+ assert_eq!(m.len(), 1);
+ assert!(m.insert(0, 0));
+ assert_eq!(m.len(), 2);
+ assert!(m.insert(4, 8));
+ assert_eq!(m.len(), 3);
+ assert!(m.remove(&3));
+ assert_eq!(m.len(), 2);
+ assert!(!m.remove(&5));
+ assert_eq!(m.len(), 2);
+ assert!(m.insert(2, 4));
+ assert_eq!(m.len(), 3);
+ assert!(m.insert(1, 2));
+ assert_eq!(m.len(), 4);
+ }
+
+ #[test]
+ fn test_iterator() {
+ let mut m = TreeMap::new();
+
+ assert!(m.insert(3i, 6i));
+ assert!(m.insert(0, 0));
+ assert!(m.insert(4, 8));
+ assert!(m.insert(2, 4));
+ assert!(m.insert(1, 2));
+
+ let mut n = 0;
+ for (k, v) in m.iter() {
+ assert_eq!(*k, n);
+ assert_eq!(*v, n * 2);
+ n += 1;
+ }
+ assert_eq!(n, 5);
+ }
+
+ #[test]
+ fn test_interval_iteration() {
+ let mut m = TreeMap::new();
+ for i in range(1i, 100i) {
+ assert!(m.insert(i * 2, i * 4));
+ }
+
+ for i in range(1i, 198i) {
+ let mut lb_it = m.lower_bound(&i);
+ let (&k, &v) = lb_it.next().unwrap();
+ let lb = i + i % 2;
+ assert_eq!(lb, k);
+ assert_eq!(lb * 2, v);
+
+ let mut ub_it = m.upper_bound(&i);
+ let (&k, &v) = ub_it.next().unwrap();
+ let ub = i + 2 - i % 2;
+ assert_eq!(ub, k);
+ assert_eq!(ub * 2, v);
+ }
+ let mut end_it = m.lower_bound(&199);
+ assert_eq!(end_it.next(), None);
+ }
+
+ #[test]
+ fn test_rev_iter() {
+ let mut m = TreeMap::new();
+
+ assert!(m.insert(3i, 6i));
+ assert!(m.insert(0, 0));
+ assert!(m.insert(4, 8));
+ assert!(m.insert(2, 4));
+ assert!(m.insert(1, 2));
+
+ let mut n = 4;
+ for (k, v) in m.rev_iter() {
+ assert_eq!(*k, n);
+ assert_eq!(*v, n * 2);
+ n -= 1;
+ }
+ }
+
+ #[test]
+ fn test_mut_iter() {
+ let mut m = TreeMap::new();
+ for i in range(0u, 10) {
+ assert!(m.insert(i, 100 * i));
+ }
+
+ for (i, (&k, v)) in m.iter_mut().enumerate() {
+ *v += k * 10 + i; // 000 + 00 + 0, 100 + 10 + 1, ...
+ }
+
+ for (&k, &v) in m.iter() {
+ assert_eq!(v, 111 * k);
+ }
+ }
+ #[test]
+ fn test_mut_rev_iter() {
+ let mut m = TreeMap::new();
+ for i in range(0u, 10) {
+ assert!(m.insert(i, 100 * i));
+ }
+
+ for (i, (&k, v)) in m.rev_iter_mut().enumerate() {
+ *v += k * 10 + (9 - i); // 900 + 90 + (9 - 0), 800 + 80 + (9 - 1), ...
+ }
+
+ for (&k, &v) in m.iter() {
+ assert_eq!(v, 111 * k);
+ }
+ }
+
+ #[test]
+ fn test_mut_interval_iter() {
+ let mut m_lower = TreeMap::new();
+ let mut m_upper = TreeMap::new();
+ for i in range(1i, 100i) {
+ assert!(m_lower.insert(i * 2, i * 4));
+ assert!(m_upper.insert(i * 2, i * 4));
+ }
+
+ for i in range(1i, 199) {
+ let mut lb_it = m_lower.lower_bound_mut(&i);
+ let (&k, v) = lb_it.next().unwrap();
+ let lb = i + i % 2;
+ assert_eq!(lb, k);
+ *v -= k;
+ }
+ for i in range(0i, 198) {
+ let mut ub_it = m_upper.upper_bound_mut(&i);
+ let (&k, v) = ub_it.next().unwrap();
+ let ub = i + 2 - i % 2;
+ assert_eq!(ub, k);
+ *v -= k;
+ }
+
+ assert!(m_lower.lower_bound_mut(&199).next().is_none());
+
+ assert!(m_upper.upper_bound_mut(&198).next().is_none());
+
+ assert!(m_lower.iter().all(|(_, &x)| x == 0));
+ assert!(m_upper.iter().all(|(_, &x)| x == 0));
+ }
+
+ #[test]
+ fn test_keys() {
+ let vec = vec![(1i, 'a'), (2i, 'b'), (3i, 'c')];
+ let map = vec.into_iter().collect::<TreeMap<int, char>>();
+ let keys = map.keys().map(|&k| k).collect::<Vec<int>>();
+ assert_eq!(keys.len(), 3);
+ assert!(keys.contains(&1));
+ assert!(keys.contains(&2));
+ assert!(keys.contains(&3));
+ }
+
+ #[test]
+ fn test_values() {
+ let vec = vec![(1i, 'a'), (2i, 'b'), (3i, 'c')];
+ let map = vec.into_iter().collect::<TreeMap<int, char>>();
+ let values = map.values().map(|&v| v).collect::<Vec<char>>();
+ assert_eq!(values.len(), 3);
+ assert!(values.contains(&'a'));
+ assert!(values.contains(&'b'));
+ assert!(values.contains(&'c'));
+ }
+
+ #[test]
+ fn test_eq() {
+ let mut a = TreeMap::new();
+ let mut b = TreeMap::new();
+
+ assert!(a == b);
+ assert!(a.insert(0i, 5i));
+ assert!(a != b);
+ assert!(b.insert(0, 4));
+ assert!(a != b);
+ assert!(a.insert(5, 19));
+ assert!(a != b);
+ assert!(!b.insert(0, 5));
+ assert!(a != b);
+ assert!(b.insert(5, 19));
+ assert!(a == b);
+ }
+
+ #[test]
+ fn test_lt() {
+ let mut a = TreeMap::new();
+ let mut b = TreeMap::new();
+
+ assert!(!(a < b) && !(b < a));
+ assert!(b.insert(0i, 5i));
+ assert!(a < b);
+ assert!(a.insert(0, 7));
+ assert!(!(a < b) && b < a);
+ assert!(b.insert(-2, 0));
+ assert!(b < a);
+ assert!(a.insert(-5, 2));
+ assert!(a < b);
+ assert!(a.insert(6, 2));
+ assert!(a < b && !(b < a));
+ }
+
+ #[test]
+ fn test_ord() {
+ let mut a = TreeMap::new();
+ let mut b = TreeMap::new();
+
+ assert!(a <= b && a >= b);
+ assert!(a.insert(1i, 1i));
+ assert!(a > b && a >= b);
+ assert!(b < a && b <= a);
+ assert!(b.insert(2, 2));
+ assert!(b > a && b >= a);
+ assert!(a < b && a <= b);
+ }
+
+ #[test]
+ fn test_show() {
+ let mut map: TreeMap<int, int> = TreeMap::new();
+ let empty: TreeMap<int, int> = TreeMap::new();
+
+ map.insert(1, 2);
+ map.insert(3, 4);
+
+ let map_str = format!("{}", map);
+
+ assert!(map_str == "{1: 2, 3: 4}".to_string());
+ assert_eq!(format!("{}", empty), "{}".to_string());
+ }
+
+ #[test]
+ fn test_lazy_iterator() {
+ let mut m = TreeMap::new();
+ let (x1, y1) = (2i, 5i);
+ let (x2, y2) = (9, 12);
+ let (x3, y3) = (20, -3);
+ let (x4, y4) = (29, 5);
+ let (x5, y5) = (103, 3);
+
+ assert!(m.insert(x1, y1));
+ assert!(m.insert(x2, y2));
+ assert!(m.insert(x3, y3));
+ assert!(m.insert(x4, y4));
+ assert!(m.insert(x5, y5));
+
+ let m = m;
+ let mut a = m.iter();
+
+ assert_eq!(a.next().unwrap(), (&x1, &y1));
+ assert_eq!(a.next().unwrap(), (&x2, &y2));
+ assert_eq!(a.next().unwrap(), (&x3, &y3));
+ assert_eq!(a.next().unwrap(), (&x4, &y4));
+ assert_eq!(a.next().unwrap(), (&x5, &y5));
+
+ assert!(a.next().is_none());
+
+ let mut b = m.iter();
+
+ let expected = [(&x1, &y1), (&x2, &y2), (&x3, &y3), (&x4, &y4),
+ (&x5, &y5)];
+ let mut i = 0;
+
+ for x in b {
+ assert_eq!(expected[i], x);
+ i += 1;
+
+ if i == 2 {
+ break
+ }
+ }
+
+ for x in b {
+ assert_eq!(expected[i], x);
+ i += 1;
+ }
+ }
+
+ #[test]
+ fn test_from_iter() {
+ let xs = [(1i, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+ let map: TreeMap<int, int> = xs.iter().map(|&x| x).collect();
+
+ for &(k, v) in xs.iter() {
+ assert_eq!(map.find(&k), Some(&v));
+ }
+ }
+
+ #[test]
+ fn test_index() {
+ let mut map: TreeMap<int, int> = TreeMap::new();
+
+ map.insert(1, 2);
+ map.insert(2, 1);
+ map.insert(3, 4);
+
+ assert_eq!(map[2], 1);
+ }
+
+ #[test]
+ #[should_fail]
+ fn test_index_nonexistent() {
+ let mut map: TreeMap<int, int> = TreeMap::new();
+
+ map.insert(1, 2);
+ map.insert(2, 1);
+ map.insert(3, 4);
+
+ map[4];
+ }
+
+ #[test]
+ fn test_swap() {
+ let mut m = TreeMap::new();
+ assert_eq!(m.swap(1u, 2i), None);
+ assert_eq!(m.swap(1u, 3i), Some(2));
+ assert_eq!(m.swap(1u, 4i), Some(3));
+ }
+
+ #[test]
+ fn test_pop() {
+ let mut m = TreeMap::new();
+ m.insert(1u, 2i);
+ assert_eq!(m.pop(&1), Some(2));
+ assert_eq!(m.pop(&1), None);
+ }
+}
+
+#[cfg(test)]
+mod bench {
+ use std::prelude::*;
+ use std::rand::{weak_rng, Rng};
+ use test::{Bencher, black_box};
+
+ use super::TreeMap;
+ use bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n};
+
+ #[bench]
+ pub fn insert_rand_100(b: &mut Bencher) {
+ let mut m : TreeMap<uint,uint> = TreeMap::new();
+ insert_rand_n(100, &mut m, b,
+ |m, i| { m.insert(i, 1); },
+ |m, i| { m.remove(&i); });
+ }
+
+ #[bench]
+ pub fn insert_rand_10_000(b: &mut Bencher) {
+ let mut m : TreeMap<uint,uint> = TreeMap::new();
+ insert_rand_n(10_000, &mut m, b,
+ |m, i| { m.insert(i, 1); },
+ |m, i| { m.remove(&i); });
+ }
+
+ // Insert seq
+ #[bench]
+ pub fn insert_seq_100(b: &mut Bencher) {
+ let mut m : TreeMap<uint,uint> = TreeMap::new();
+ insert_seq_n(100, &mut m, b,
+ |m, i| { m.insert(i, 1); },
+ |m, i| { m.remove(&i); });
+ }
+
+ #[bench]
+ pub fn insert_seq_10_000(b: &mut Bencher) {
+ let mut m : TreeMap<uint,uint> = TreeMap::new();
+ insert_seq_n(10_000, &mut m, b,
+ |m, i| { m.insert(i, 1); },
+ |m, i| { m.remove(&i); });
+ }
+
+ // Find rand
+ #[bench]
+ pub fn find_rand_100(b: &mut Bencher) {
+ let mut m : TreeMap<uint,uint> = TreeMap::new();
+ find_rand_n(100, &mut m, b,
+ |m, i| { m.insert(i, 1); },
+ |m, i| { m.find(&i); });
+ }
+
+ #[bench]
+ pub fn find_rand_10_000(b: &mut Bencher) {
+ let mut m : TreeMap<uint,uint> = TreeMap::new();
+ find_rand_n(10_000, &mut m, b,
+ |m, i| { m.insert(i, 1); },
+ |m, i| { m.find(&i); });
+ }
+
+ // Find seq
+ #[bench]
+ pub fn find_seq_100(b: &mut Bencher) {
+ let mut m : TreeMap<uint,uint> = TreeMap::new();
+ find_seq_n(100, &mut m, b,
+ |m, i| { m.insert(i, 1); },
+ |m, i| { m.find(&i); });
+ }
+
+ #[bench]
+ pub fn find_seq_10_000(b: &mut Bencher) {
+ let mut m : TreeMap<uint,uint> = TreeMap::new();
+ find_seq_n(10_000, &mut m, b,
+ |m, i| { m.insert(i, 1); },
+ |m, i| { m.find(&i); });
+ }
+
+ fn bench_iter(b: &mut Bencher, size: uint) {
+ let mut map = TreeMap::<uint, uint>::new();
+ let mut rng = weak_rng();
+
+ for _ in range(0, size) {
+ map.swap(rng.gen(), rng.gen());
+ }
+
+ b.iter(|| {
+ for entry in map.iter() {
+ black_box(entry);
+ }
+ });
+ }
+
+ #[bench]
+ pub fn iter_20(b: &mut Bencher) {
+ bench_iter(b, 20);
+ }
+
+ #[bench]
+ pub fn iter_1000(b: &mut Bencher) {
+ bench_iter(b, 1000);
+ }
+
+ #[bench]
+ pub fn iter_100000(b: &mut Bencher) {
+ bench_iter(b, 100000);
+ }
+}
+
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+//! Maps are collections of unique keys with corresponding values, and sets are
+//! just unique keys without a corresponding value. The `Map` and `Set` traits in
+//! `std::container` define the basic interface.
+//!
+//! This crate defines the `TreeMap` and `TreeSet` types. Their keys must implement `Ord`.
+//!
+//! `TreeMap`s are ordered.
+//!
+//! ## Example
+//!
+//! ```{rust}
+//! use std::collections::TreeSet;
+//!
+//! let mut tree_set = TreeSet::new();
+//!
+//! tree_set.insert(2i);
+//! tree_set.insert(1i);
+//! tree_set.insert(3i);
+//!
+//! for i in tree_set.iter() {
+//! println!("{}", i) // prints 1, then 2, then 3
+//! }
+//! ```
+
+pub mod map;
+pub mod set;
\ No newline at end of file
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+use core::prelude::*;
+
+use core::default::Default;
+use core::fmt;
+use core::fmt::Show;
+use core::iter::Peekable;
+use core::iter;
+use std::hash::{Writer, Hash};
+
+use tree_map::{TreeMap, Entries, RevEntries, MoveEntries};
+
+/// An implementation of the `Set` trait on top of the `TreeMap` container. The
+/// only requirement is that the type of the elements contained ascribes to the
+/// `Ord` trait.
+///
+/// ## Example
+///
+/// ```{rust}
+/// use std::collections::TreeSet;
+///
+/// let mut set = TreeSet::new();
+///
+/// set.insert(2i);
+/// set.insert(1i);
+/// set.insert(3i);
+///
+/// for i in set.iter() {
+/// println!("{}", i) // prints 1, then 2, then 3
+/// }
+///
+/// set.remove(&3);
+///
+/// if !set.contains(&3) {
+/// println!("set does not contain a 3 anymore");
+/// }
+/// ```
+///
+/// The easiest way to use `TreeSet` with a custom type is to implement `Ord`.
+/// We must also implement `PartialEq`, `Eq` and `PartialOrd`.
+///
+/// ```
+/// use std::collections::TreeSet;
+///
+/// // We need `Eq` and `PartialEq`, these can be derived.
+/// #[deriving(Eq, PartialEq)]
+/// struct Troll<'a> {
+/// name: &'a str,
+/// level: uint,
+/// }
+///
+/// // Implement `Ord` and sort trolls by level.
+/// impl<'a> Ord for Troll<'a> {
+/// fn cmp(&self, other: &Troll) -> Ordering {
+/// // If we swap `self` and `other`, we get descending ordering.
+/// self.level.cmp(&other.level)
+/// }
+/// }
+///
+/// // `PartialOrd` needs to be implemented as well.
+/// impl<'a> PartialOrd for Troll<'a> {
+/// fn partial_cmp(&self, other: &Troll) -> Option<Ordering> {
+/// Some(self.cmp(other))
+/// }
+/// }
+///
+/// let mut trolls = TreeSet::new();
+///
+/// trolls.insert(Troll { name: "Orgarr", level: 2 });
+/// trolls.insert(Troll { name: "Blargarr", level: 3 });
+/// trolls.insert(Troll { name: "Kron the Smelly One", level: 4 });
+/// trolls.insert(Troll { name: "Wartilda", level: 1 });
+///
+/// println!("You are facing {} trolls!", trolls.len());
+///
+/// // Print the trolls, ordered by level with smallest level first
+/// for x in trolls.iter() {
+/// println!("level {}: {}!", x.level, x.name);
+/// }
+///
+/// // Kill all trolls
+/// trolls.clear();
+/// assert_eq!(trolls.len(), 0);
+/// ```
+#[deriving(Clone)]
+pub struct TreeSet<T> {
+ map: TreeMap<T, ()>
+}
+
+impl<T: PartialEq + Ord> PartialEq for TreeSet<T> {
+ #[inline]
+ fn eq(&self, other: &TreeSet<T>) -> bool { self.map == other.map }
+}
+
+impl<T: Eq + Ord> Eq for TreeSet<T> {}
+
+impl<T: Ord> PartialOrd for TreeSet<T> {
+ #[inline]
+ fn partial_cmp(&self, other: &TreeSet<T>) -> Option<Ordering> {
+ self.map.partial_cmp(&other.map)
+ }
+}
+
+impl<T: Ord> Ord for TreeSet<T> {
+ #[inline]
+ fn cmp(&self, other: &TreeSet<T>) -> Ordering {
+ iter::order::cmp(self.iter(), other.iter())
+ }
+}
+
+impl<T: Ord + Show> Show for TreeSet<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ try!(write!(f, "{{"));
+
+ for (i, x) in self.iter().enumerate() {
+ if i != 0 { try!(write!(f, ", ")); }
+ try!(write!(f, "{}", *x));
+ }
+
+ write!(f, "}}")
+ }
+}
+
+impl<T: Ord> Default for TreeSet<T> {
+ #[inline]
+ fn default() -> TreeSet<T> { TreeSet::new() }
+}
+
+impl<T: Ord> TreeSet<T> {
+ /// Creates an empty `TreeSet`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeSet;
+ /// let mut set: TreeSet<int> = TreeSet::new();
+ /// ```
+ #[inline]
+ pub fn new() -> TreeSet<T> { TreeSet{map: TreeMap::new()} }
+
+ /// Gets a lazy iterator over the values in the set, in ascending order.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeSet;
+ /// let set: TreeSet<int> = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect();
+ ///
+ /// // Will print in ascending order.
+ /// for x in set.iter() {
+ /// println!("{}", x);
+ /// }
+ /// ```
+ #[inline]
+ pub fn iter<'a>(&'a self) -> SetItems<'a, T> {
+ SetItems{iter: self.map.iter()}
+ }
+
+ /// Gets a lazy iterator over the values in the set, in descending order.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeSet;
+ /// let set: TreeSet<int> = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect();
+ ///
+ /// // Will print in descending order.
+ /// for x in set.rev_iter() {
+ /// println!("{}", x);
+ /// }
+ /// ```
+ #[inline]
+ pub fn rev_iter<'a>(&'a self) -> RevSetItems<'a, T> {
+ RevSetItems{iter: self.map.rev_iter()}
+ }
+
+ /// Creates a consuming iterator, that is, one that moves each value out of the
+ /// set in ascending order. The set cannot be used after calling this.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeSet;
+ /// let set: TreeSet<int> = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect();
+ ///
+ /// // Not possible with a regular `.iter()`
+ /// let v: Vec<int> = set.into_iter().collect();
+ /// assert_eq!(v, vec![1, 2, 3, 4, 5]);
+ /// ```
+ #[inline]
+ pub fn into_iter(self) -> MoveSetItems<T> {
+ self.map.into_iter().map(|(value, _)| value)
+ }
+
+ /// Gets a lazy iterator pointing to the first value not less than `v` (greater or equal).
+ /// If all elements in the set are less than `v` empty iterator is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeSet;
+ /// let set: TreeSet<int> = [2, 4, 6, 8].iter().map(|&x| x).collect();
+ ///
+ /// assert_eq!(set.lower_bound(&4).next(), Some(&4));
+ /// assert_eq!(set.lower_bound(&5).next(), Some(&6));
+ /// assert_eq!(set.lower_bound(&10).next(), None);
+ /// ```
+ #[inline]
+ pub fn lower_bound<'a>(&'a self, v: &T) -> SetItems<'a, T> {
+ SetItems{iter: self.map.lower_bound(v)}
+ }
+
+ /// Gets a lazy iterator pointing to the first value greater than `v`.
+ /// If all elements in the set are less than or equal to `v` an
+ /// empty iterator is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeSet;
+ /// let set: TreeSet<int> = [2, 4, 6, 8].iter().map(|&x| x).collect();
+ ///
+ /// assert_eq!(set.upper_bound(&4).next(), Some(&6));
+ /// assert_eq!(set.upper_bound(&5).next(), Some(&6));
+ /// assert_eq!(set.upper_bound(&10).next(), None);
+ /// ```
+ #[inline]
+ pub fn upper_bound<'a>(&'a self, v: &T) -> SetItems<'a, T> {
+ SetItems{iter: self.map.upper_bound(v)}
+ }
+
+ /// Visits the values representing the difference, in ascending order.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeSet;
+ ///
+ /// let a: TreeSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
+ /// let b: TreeSet<int> = [3, 4, 5].iter().map(|&x| x).collect();
+ ///
+ /// // Can be seen as `a - b`.
+ /// for x in a.difference(&b) {
+ /// println!("{}", x); // Print 1 then 2
+ /// }
+ ///
+ /// let diff: TreeSet<int> = a.difference(&b).map(|&x| x).collect();
+ /// assert_eq!(diff, [1, 2].iter().map(|&x| x).collect());
+ ///
+ /// // Note that difference is not symmetric,
+ /// // and `b - a` means something else:
+ /// let diff: TreeSet<int> = b.difference(&a).map(|&x| x).collect();
+ /// assert_eq!(diff, [4, 5].iter().map(|&x| x).collect());
+ /// ```
+ pub fn difference<'a>(&'a self, other: &'a TreeSet<T>) -> DifferenceItems<'a, T> {
+ DifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()}
+ }
+
+ /// Visits the values representing the symmetric difference, in ascending order.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeSet;
+ ///
+ /// let a: TreeSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
+ /// let b: TreeSet<int> = [3, 4, 5].iter().map(|&x| x).collect();
+ ///
+ /// // Print 1, 2, 4, 5 in ascending order.
+ /// for x in a.symmetric_difference(&b) {
+ /// println!("{}", x);
+ /// }
+ ///
+ /// let diff1: TreeSet<int> = a.symmetric_difference(&b).map(|&x| x).collect();
+ /// let diff2: TreeSet<int> = b.symmetric_difference(&a).map(|&x| x).collect();
+ ///
+ /// assert_eq!(diff1, diff2);
+ /// assert_eq!(diff1, [1, 2, 4, 5].iter().map(|&x| x).collect());
+ /// ```
+ pub fn symmetric_difference<'a>(&'a self, other: &'a TreeSet<T>)
+ -> SymDifferenceItems<'a, T> {
+ SymDifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()}
+ }
+
+ /// Visits the values representing the intersection, in ascending order.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeSet;
+ ///
+ /// let a: TreeSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
+ /// let b: TreeSet<int> = [2, 3, 4].iter().map(|&x| x).collect();
+ ///
+ /// // Print 2, 3 in ascending order.
+ /// for x in a.intersection(&b) {
+ /// println!("{}", x);
+ /// }
+ ///
+ /// let diff: TreeSet<int> = a.intersection(&b).map(|&x| x).collect();
+ /// assert_eq!(diff, [2, 3].iter().map(|&x| x).collect());
+ /// ```
+ pub fn intersection<'a>(&'a self, other: &'a TreeSet<T>)
+ -> IntersectionItems<'a, T> {
+ IntersectionItems{a: self.iter().peekable(), b: other.iter().peekable()}
+ }
+
+ /// Visits the values representing the union, in ascending order.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeSet;
+ ///
+ /// let a: TreeSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
+ /// let b: TreeSet<int> = [3, 4, 5].iter().map(|&x| x).collect();
+ ///
+ /// // Print 1, 2, 3, 4, 5 in ascending order.
+ /// for x in a.union(&b) {
+ /// println!("{}", x);
+ /// }
+ ///
+ /// let diff: TreeSet<int> = a.union(&b).map(|&x| x).collect();
+ /// assert_eq!(diff, [1, 2, 3, 4, 5].iter().map(|&x| x).collect());
+ /// ```
+ pub fn union<'a>(&'a self, other: &'a TreeSet<T>) -> UnionItems<'a, T> {
+ UnionItems{a: self.iter().peekable(), b: other.iter().peekable()}
+ }
+
+ /// Return the number of elements in the set
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeSet;
+ ///
+ /// let mut v = TreeSet::new();
+ /// assert_eq!(v.len(), 0);
+ /// v.insert(1i);
+ /// assert_eq!(v.len(), 1);
+ /// ```
+ #[inline]
+ pub fn len(&self) -> uint { self.map.len() }
+
+ /// Returns true if the set contains no elements
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeSet;
+ ///
+ /// let mut v = TreeSet::new();
+ /// assert!(v.is_empty());
+ /// v.insert(1i);
+ /// assert!(!v.is_empty());
+ /// ```
+ pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+ /// Clears the set, removing all values.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeSet;
+ ///
+ /// let mut v = TreeSet::new();
+ /// v.insert(1i);
+ /// v.clear();
+ /// assert!(v.is_empty());
+ /// ```
+ #[inline]
+ pub fn clear(&mut self) { self.map.clear() }
+
+ /// Returns `true` if the set contains a value.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeSet;
+ ///
+ /// let set: TreeSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
+ /// assert_eq!(set.contains(&1), true);
+ /// assert_eq!(set.contains(&4), false);
+ /// ```
+ #[inline]
+ pub fn contains(&self, value: &T) -> bool {
+ self.map.contains_key(value)
+ }
+
+ /// Returns `true` if the set has no elements in common with `other`.
+ /// This is equivalent to checking for an empty intersection.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeSet;
+ ///
+ /// let a: TreeSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
+ /// let mut b: TreeSet<int> = TreeSet::new();
+ ///
+ /// assert_eq!(a.is_disjoint(&b), true);
+ /// b.insert(4);
+ /// assert_eq!(a.is_disjoint(&b), true);
+ /// b.insert(1);
+ /// assert_eq!(a.is_disjoint(&b), false);
+ /// ```
+ pub fn is_disjoint(&self, other: &TreeSet<T>) -> bool {
+ self.intersection(other).next().is_none()
+ }
+
+ /// Returns `true` if the set is a subset of another.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeSet;
+ ///
+ /// let sup: TreeSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
+ /// let mut set: TreeSet<int> = TreeSet::new();
+ ///
+ /// assert_eq!(set.is_subset(&sup), true);
+ /// set.insert(2);
+ /// assert_eq!(set.is_subset(&sup), true);
+ /// set.insert(4);
+ /// assert_eq!(set.is_subset(&sup), false);
+ /// ```
+ pub fn is_subset(&self, other: &TreeSet<T>) -> bool {
+ let mut x = self.iter();
+ let mut y = other.iter();
+ let mut a = x.next();
+ let mut b = y.next();
+ while a.is_some() {
+ if b.is_none() {
+ return false;
+ }
+
+ let a1 = a.unwrap();
+ let b1 = b.unwrap();
+
+ match b1.cmp(a1) {
+ Less => (),
+ Greater => return false,
+ Equal => a = x.next(),
+ }
+
+ b = y.next();
+ }
+ true
+ }
+
+ /// Returns `true` if the set is a superset of another.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TreeSet;
+ ///
+ /// let sub: TreeSet<int> = [1i, 2].iter().map(|&x| x).collect();
+ /// let mut set: TreeSet<int> = TreeSet::new();
+ ///
+ /// assert_eq!(set.is_superset(&sub), false);
+ ///
+ /// set.insert(0);
+ /// set.insert(1);
+ /// assert_eq!(set.is_superset(&sub), false);
+ ///
+ /// set.insert(2);
+ /// assert_eq!(set.is_superset(&sub), true);
+ /// ```
+ pub fn is_superset(&self, other: &TreeSet<T>) -> bool {
+ other.is_subset(self)
+ }
+
+ /// Adds a value to the set. Returns `true` if the value was not already
+ /// present in the set.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let mut set = BTreeSet::new();
+ ///
+ /// assert_eq!(set.insert(2i), true);
+ /// assert_eq!(set.insert(2i), false);
+ /// assert_eq!(set.len(), 1);
+ /// ```
+ #[inline]
+ pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
+
+ /// Removes a value from the set. Returns `true` if the value was
+ /// present in the set.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let mut set = BTreeSet::new();
+ ///
+ /// set.insert(2i);
+ /// assert_eq!(set.remove(&2), true);
+ /// assert_eq!(set.remove(&2), false);
+ /// ```
+ #[inline]
+ pub fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
+}
+
+/// A lazy forward iterator over a set.
+pub struct SetItems<'a, T:'a> {
+ iter: Entries<'a, T, ()>
+}
+
+/// A lazy backward iterator over a set.
+pub struct RevSetItems<'a, T:'a> {
+ iter: RevEntries<'a, T, ()>
+}
+
+/// A lazy forward iterator over a set that consumes the set while iterating.
+pub type MoveSetItems<T> = iter::Map<'static, (T, ()), T, MoveEntries<T, ()>>;
+
+/// A lazy iterator producing elements in the set difference (in-order).
+pub struct DifferenceItems<'a, T:'a> {
+ a: Peekable<&'a T, SetItems<'a, T>>,
+ b: Peekable<&'a T, SetItems<'a, T>>,
+}
+
+/// A lazy iterator producing elements in the set symmetric difference (in-order).
+pub struct SymDifferenceItems<'a, T:'a> {
+ a: Peekable<&'a T, SetItems<'a, T>>,
+ b: Peekable<&'a T, SetItems<'a, T>>,
+}
+
+/// A lazy iterator producing elements in the set intersection (in-order).
+pub struct IntersectionItems<'a, T:'a> {
+ a: Peekable<&'a T, SetItems<'a, T>>,
+ b: Peekable<&'a T, SetItems<'a, T>>,
+}
+
+/// A lazy iterator producing elements in the set union (in-order).
+pub struct UnionItems<'a, T:'a> {
+ a: Peekable<&'a T, SetItems<'a, T>>,
+ b: Peekable<&'a T, SetItems<'a, T>>,
+}
+
+/// Compare `x` and `y`, but return `short` if x is None and `long` if y is None
+fn cmp_opt<T: Ord>(x: Option<&T>, y: Option<&T>,
+ short: Ordering, long: Ordering) -> Ordering {
+ match (x, y) {
+ (None , _ ) => short,
+ (_ , None ) => long,
+ (Some(x1), Some(y1)) => x1.cmp(y1),
+ }
+}
+
+
+impl<'a, T> Iterator<&'a T> for SetItems<'a, T> {
+ #[inline]
+ fn next(&mut self) -> Option<&'a T> {
+ self.iter.next().map(|(value, _)| value)
+ }
+}
+
+impl<'a, T> Iterator<&'a T> for RevSetItems<'a, T> {
+ #[inline]
+ fn next(&mut self) -> Option<&'a T> {
+ self.iter.next().map(|(value, _)| value)
+ }
+}
+
+impl<'a, T: Ord> Iterator<&'a T> for DifferenceItems<'a, T> {
+ fn next(&mut self) -> Option<&'a T> {
+ loop {
+ match cmp_opt(self.a.peek(), self.b.peek(), Less, Less) {
+ Less => return self.a.next(),
+ Equal => { self.a.next(); self.b.next(); }
+ Greater => { self.b.next(); }
+ }
+ }
+ }
+}
+
+impl<'a, T: Ord> Iterator<&'a T> for SymDifferenceItems<'a, T> {
+ fn next(&mut self) -> Option<&'a T> {
+ loop {
+ match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) {
+ Less => return self.a.next(),
+ Equal => { self.a.next(); self.b.next(); }
+ Greater => return self.b.next(),
+ }
+ }
+ }
+}
+
+impl<'a, T: Ord> Iterator<&'a T> for IntersectionItems<'a, T> {
+ fn next(&mut self) -> Option<&'a T> {
+ loop {
+ let o_cmp = match (self.a.peek(), self.b.peek()) {
+ (None , _ ) => None,
+ (_ , None ) => None,
+ (Some(a1), Some(b1)) => Some(a1.cmp(b1)),
+ };
+ match o_cmp {
+ None => return None,
+ Some(Less) => { self.a.next(); }
+ Some(Equal) => { self.b.next(); return self.a.next() }
+ Some(Greater) => { self.b.next(); }
+ }
+ }
+ }
+}
+
+impl<'a, T: Ord> Iterator<&'a T> for UnionItems<'a, T> {
+ fn next(&mut self) -> Option<&'a T> {
+ loop {
+ match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) {
+ Less => return self.a.next(),
+ Equal => { self.b.next(); return self.a.next() }
+ Greater => return self.b.next(),
+ }
+ }
+ }
+}
+
+impl<T: Ord> FromIterator<T> for TreeSet<T> {
+ fn from_iter<Iter: Iterator<T>>(iter: Iter) -> TreeSet<T> {
+ let mut set = TreeSet::new();
+ set.extend(iter);
+ set
+ }
+}
+
+impl<T: Ord> Extendable<T> for TreeSet<T> {
+ #[inline]
+ fn extend<Iter: Iterator<T>>(&mut self, mut iter: Iter) {
+ for elem in iter {
+ self.insert(elem);
+ }
+ }
+}
+
+impl<S: Writer, T: Ord + Hash<S>> Hash<S> for TreeSet<T> {
+ fn hash(&self, state: &mut S) {
+ for elt in self.iter() {
+ elt.hash(state);
+ }
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use std::prelude::*;
+ use std::hash;
+
+ use super::TreeSet;
+
+ #[test]
+ fn test_clear() {
+ let mut s = TreeSet::new();
+ s.clear();
+ assert!(s.insert(5i));
+ assert!(s.insert(12));
+ assert!(s.insert(19));
+ s.clear();
+ assert!(!s.contains(&5));
+ assert!(!s.contains(&12));
+ assert!(!s.contains(&19));
+ assert!(s.is_empty());
+ }
+
+ #[test]
+ fn test_disjoint() {
+ let mut xs = TreeSet::new();
+ let mut ys = TreeSet::new();
+ assert!(xs.is_disjoint(&ys));
+ assert!(ys.is_disjoint(&xs));
+ assert!(xs.insert(5i));
+ assert!(ys.insert(11i));
+ assert!(xs.is_disjoint(&ys));
+ assert!(ys.is_disjoint(&xs));
+ assert!(xs.insert(7));
+ assert!(xs.insert(19));
+ assert!(xs.insert(4));
+ assert!(ys.insert(2));
+ assert!(ys.insert(-11));
+ assert!(xs.is_disjoint(&ys));
+ assert!(ys.is_disjoint(&xs));
+ assert!(ys.insert(7));
+ assert!(!xs.is_disjoint(&ys));
+ assert!(!ys.is_disjoint(&xs));
+ }
+
+ #[test]
+ fn test_subset_and_superset() {
+ let mut a = TreeSet::new();
+ assert!(a.insert(0i));
+ assert!(a.insert(5));
+ assert!(a.insert(11));
+ assert!(a.insert(7));
+
+ let mut b = TreeSet::new();
+ assert!(b.insert(0i));
+ assert!(b.insert(7));
+ assert!(b.insert(19));
+ assert!(b.insert(250));
+ assert!(b.insert(11));
+ assert!(b.insert(200));
+
+ assert!(!a.is_subset(&b));
+ assert!(!a.is_superset(&b));
+ assert!(!b.is_subset(&a));
+ assert!(!b.is_superset(&a));
+
+ assert!(b.insert(5));
+
+ assert!(a.is_subset(&b));
+ assert!(!a.is_superset(&b));
+ assert!(!b.is_subset(&a));
+ assert!(b.is_superset(&a));
+ }
+
+ #[test]
+ fn test_iterator() {
+ let mut m = TreeSet::new();
+
+ assert!(m.insert(3i));
+ assert!(m.insert(0));
+ assert!(m.insert(4));
+ assert!(m.insert(2));
+ assert!(m.insert(1));
+
+ let mut n = 0;
+ for x in m.iter() {
+ assert_eq!(*x, n);
+ n += 1
+ }
+ }
+
+ #[test]
+ fn test_rev_iter() {
+ let mut m = TreeSet::new();
+
+ assert!(m.insert(3i));
+ assert!(m.insert(0));
+ assert!(m.insert(4));
+ assert!(m.insert(2));
+ assert!(m.insert(1));
+
+ let mut n = 4;
+ for x in m.rev_iter() {
+ assert_eq!(*x, n);
+ n -= 1;
+ }
+ }
+
+ #[test]
+ fn test_move_iter() {
+ let s: TreeSet<int> = range(0i, 5).collect();
+
+ let mut n = 0;
+ for x in s.into_iter() {
+ assert_eq!(x, n);
+ n += 1;
+ }
+ }
+
+ #[test]
+ fn test_move_iter_size_hint() {
+ let s: TreeSet<int> = vec!(0i, 1).into_iter().collect();
+
+ let mut it = s.into_iter();
+
+ assert_eq!(it.size_hint(), (2, Some(2)));
+ assert!(it.next() != None);
+
+ assert_eq!(it.size_hint(), (1, Some(1)));
+ assert!(it.next() != None);
+
+ assert_eq!(it.size_hint(), (0, Some(0)));
+ assert_eq!(it.next(), None);
+ }
+
+ #[test]
+ fn test_clone_eq() {
+ let mut m = TreeSet::new();
+
+ m.insert(1i);
+ m.insert(2);
+
+ assert!(m.clone() == m);
+ }
+
+ #[test]
+ fn test_hash() {
+ let mut x = TreeSet::new();
+ let mut y = TreeSet::new();
+
+ x.insert(1i);
+ x.insert(2);
+ x.insert(3);
+
+ y.insert(3i);
+ y.insert(2);
+ y.insert(1);
+
+ assert!(hash::hash(&x) == hash::hash(&y));
+ }
+
+ fn check(a: &[int],
+ b: &[int],
+ expected: &[int],
+ f: |&TreeSet<int>, &TreeSet<int>, f: |&int| -> bool| -> bool) {
+ let mut set_a = TreeSet::new();
+ let mut set_b = TreeSet::new();
+
+ for x in a.iter() { assert!(set_a.insert(*x)) }
+ for y in b.iter() { assert!(set_b.insert(*y)) }
+
+ let mut i = 0;
+ f(&set_a, &set_b, |x| {
+ assert_eq!(*x, expected[i]);
+ i += 1;
+ true
+ });
+ assert_eq!(i, expected.len());
+ }
+
+ #[test]
+ fn test_intersection() {
+ fn check_intersection(a: &[int], b: &[int], expected: &[int]) {
+ check(a, b, expected, |x, y, f| x.intersection(y).all(f))
+ }
+
+ check_intersection([], [], []);
+ check_intersection([1, 2, 3], [], []);
+ check_intersection([], [1, 2, 3], []);
+ check_intersection([2], [1, 2, 3], [2]);
+ check_intersection([1, 2, 3], [2], [2]);
+ check_intersection([11, 1, 3, 77, 103, 5, -5],
+ [2, 11, 77, -9, -42, 5, 3],
+ [3, 5, 11, 77]);
+ }
+
+ #[test]
+ fn test_difference() {
+ fn check_difference(a: &[int], b: &[int], expected: &[int]) {
+ check(a, b, expected, |x, y, f| x.difference(y).all(f))
+ }
+
+ check_difference([], [], []);
+ check_difference([1, 12], [], [1, 12]);
+ check_difference([], [1, 2, 3, 9], []);
+ check_difference([1, 3, 5, 9, 11],
+ [3, 9],
+ [1, 5, 11]);
+ check_difference([-5, 11, 22, 33, 40, 42],
+ [-12, -5, 14, 23, 34, 38, 39, 50],
+ [11, 22, 33, 40, 42]);
+ }
+
+ #[test]
+ fn test_symmetric_difference() {
+ fn check_symmetric_difference(a: &[int], b: &[int],
+ expected: &[int]) {
+ check(a, b, expected, |x, y, f| x.symmetric_difference(y).all(f))
+ }
+
+ check_symmetric_difference([], [], []);
+ check_symmetric_difference([1, 2, 3], [2], [1, 3]);
+ check_symmetric_difference([2], [1, 2, 3], [1, 3]);
+ check_symmetric_difference([1, 3, 5, 9, 11],
+ [-2, 3, 9, 14, 22],
+ [-2, 1, 5, 11, 14, 22]);
+ }
+
+ #[test]
+ fn test_union() {
+ fn check_union(a: &[int], b: &[int],
+ expected: &[int]) {
+ check(a, b, expected, |x, y, f| x.union(y).all(f))
+ }
+
+ check_union([], [], []);
+ check_union([1, 2, 3], [2], [1, 2, 3]);
+ check_union([2], [1, 2, 3], [1, 2, 3]);
+ check_union([1, 3, 5, 9, 11, 16, 19, 24],
+ [-2, 1, 5, 9, 13, 19],
+ [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]);
+ }
+
+ #[test]
+ fn test_zip() {
+ let mut x = TreeSet::new();
+ x.insert(5u);
+ x.insert(12u);
+ x.insert(11u);
+
+ let mut y = TreeSet::new();
+ y.insert("foo");
+ y.insert("bar");
+
+ let x = x;
+ let y = y;
+ let mut z = x.iter().zip(y.iter());
+
+ // FIXME: #5801: this needs a type hint to compile...
+ let result: Option<(&uint, & &'static str)> = z.next();
+ assert_eq!(result.unwrap(), (&5u, &("bar")));
+
+ let result: Option<(&uint, & &'static str)> = z.next();
+ assert_eq!(result.unwrap(), (&11u, &("foo")));
+
+ let result: Option<(&uint, & &'static str)> = z.next();
+ assert!(result.is_none());
+ }
+
+ #[test]
+ fn test_from_iter() {
+ let xs = [1i, 2, 3, 4, 5, 6, 7, 8, 9];
+
+ let set: TreeSet<int> = xs.iter().map(|&x| x).collect();
+
+ for x in xs.iter() {
+ assert!(set.contains(x));
+ }
+ }
+
+ #[test]
+ fn test_show() {
+ let mut set: TreeSet<int> = TreeSet::new();
+ let empty: TreeSet<int> = TreeSet::new();
+
+ set.insert(1);
+ set.insert(2);
+
+ let set_str = format!("{}", set);
+
+ assert!(set_str == "{1, 2}".to_string());
+ assert_eq!(format!("{}", empty), "{}".to_string());
+ }
+}
+++ /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.
-
-//! Maps are collections of unique keys with corresponding values, and sets are
-//! just unique keys without a corresponding value. The `Map` and `Set` traits in
-//! `std::container` define the basic interface.
-//!
-//! This crate defines the `TreeMap` and `TreeSet` types. Their keys must implement `Ord`.
-//!
-//! `TreeMap`s are ordered.
-//!
-//! ## Example
-//!
-//! ```{rust}
-//! use std::collections::TreeSet;
-//!
-//! let mut tree_set = TreeSet::new();
-//!
-//! tree_set.insert(2i);
-//! tree_set.insert(1i);
-//! tree_set.insert(3i);
-//!
-//! for i in tree_set.iter() {
-//! println!("{}", i) // prints 1, then 2, then 3
-//! }
-//! ```
-
-use core::prelude::*;
-
-use alloc::boxed::Box;
-use core::default::Default;
-use core::fmt;
-use core::fmt::Show;
-use core::iter::Peekable;
-use core::iter;
-use core::mem::{replace, swap};
-use core::ptr;
-use std::hash::{Writer, Hash};
-
-use vec::Vec;
-
-/// This is implemented as an AA tree, which is a simplified variation of
-/// a red-black tree where red (horizontal) nodes can only be added
-/// as a right child. The time complexity is the same, and re-balancing
-/// operations are more frequent but also cheaper.
-///
-/// # Example
-///
-/// ```
-/// use std::collections::TreeMap;
-///
-/// let mut map = TreeMap::new();
-///
-/// map.insert(2i, "bar");
-/// map.insert(1i, "foo");
-/// map.insert(3i, "quux");
-///
-/// // In ascending order by keys
-/// for (key, value) in map.iter() {
-/// println!("{}: {}", key, value);
-/// }
-///
-/// // Prints 1, 2, 3
-/// for key in map.keys() {
-/// println!("{}", key);
-/// }
-///
-/// // Prints `foo`, `bar`, `quux`
-/// for key in map.values() {
-/// println!("{}", key);
-/// }
-///
-/// map.remove(&1);
-/// assert_eq!(map.len(), 2);
-///
-/// if !map.contains_key(&1) {
-/// println!("1 is no more");
-/// }
-///
-/// for key in range(0, 4) {
-/// match map.find(&key) {
-/// Some(val) => println!("{} has a value: {}", key, val),
-/// None => println!("{} not in map", key),
-/// }
-/// }
-///
-/// map.clear();
-/// assert!(map.is_empty());
-/// ```
-///
-/// The easiest way to use `TreeMap` with a custom type as keys is to implement `Ord`.
-/// We must also implement `PartialEq`, `Eq` and `PartialOrd`.
-///
-/// ```
-/// use std::collections::TreeMap;
-///
-/// // We need `Eq` and `PartialEq`, these can be derived.
-/// #[deriving(Eq, PartialEq)]
-/// struct Troll<'a> {
-/// name: &'a str,
-/// level: uint,
-/// }
-///
-/// // Implement `Ord` and sort trolls by level.
-/// impl<'a> Ord for Troll<'a> {
-/// fn cmp(&self, other: &Troll) -> Ordering {
-/// // If we swap `self` and `other`, we get descending ordering.
-/// self.level.cmp(&other.level)
-/// }
-/// }
-///
-/// // `PartialOrd` needs to be implemented as well.
-/// impl<'a> PartialOrd for Troll<'a> {
-/// fn partial_cmp(&self, other: &Troll) -> Option<Ordering> {
-/// Some(self.cmp(other))
-/// }
-/// }
-///
-/// // Use a map to store trolls, sorted by level, and track a list of
-/// // heroes slain.
-/// let mut trolls = TreeMap::new();
-///
-/// trolls.insert(Troll { name: "Orgarr", level: 2 },
-/// vec!["King Karl"]);
-/// trolls.insert(Troll { name: "Blargarr", level: 3 },
-/// vec!["Odd"]);
-/// trolls.insert(Troll { name: "Kron the Smelly One", level: 4 },
-/// vec!["Omar the Brave", "Peter: Slayer of Trolls"]);
-/// trolls.insert(Troll { name: "Wartilda", level: 1 },
-/// vec![]);
-///
-/// println!("You are facing {} trolls!", trolls.len());
-///
-/// // Print the trolls, ordered by level with smallest level first
-/// for (troll, heroes) in trolls.iter() {
-/// let what = if heroes.len() == 1u { "hero" }
-/// else { "heroes" };
-///
-/// println!("level {}: '{}' has slain {} {}",
-/// troll.level, troll.name, heroes.len(), what);
-/// }
-///
-/// // Kill all trolls
-/// trolls.clear();
-/// assert_eq!(trolls.len(), 0);
-/// ```
-
-// Future improvements:
-
-// range search - O(log n) retrieval of an iterator from some key
-
-// (possibly) implement the overloads Python does for sets:
-// * intersection: &
-// * difference: -
-// * symmetric difference: ^
-// * union: |
-// These would be convenient since the methods work like `each`
-
-#[deriving(Clone)]
-pub struct TreeMap<K, V> {
- root: Option<Box<TreeNode<K, V>>>,
- length: uint
-}
-
-impl<K: PartialEq + Ord, V: PartialEq> PartialEq for TreeMap<K, V> {
- fn eq(&self, other: &TreeMap<K, V>) -> bool {
- self.len() == other.len() &&
- self.iter().zip(other.iter()).all(|(a, b)| a == b)
- }
-}
-
-impl<K: Eq + Ord, V: Eq> Eq for TreeMap<K, V> {}
-
-impl<K: Ord, V: PartialOrd> PartialOrd for TreeMap<K, V> {
- #[inline]
- fn partial_cmp(&self, other: &TreeMap<K, V>) -> Option<Ordering> {
- iter::order::partial_cmp(self.iter(), other.iter())
- }
-}
-
-impl<K: Ord, V: Ord> Ord for TreeMap<K, V> {
- #[inline]
- fn cmp(&self, other: &TreeMap<K, V>) -> Ordering {
- iter::order::cmp(self.iter(), other.iter())
- }
-}
-
-impl<K: Ord + Show, V: Show> Show for TreeMap<K, V> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- try!(write!(f, "{{"));
-
- for (i, (k, v)) in self.iter().enumerate() {
- if i != 0 { try!(write!(f, ", ")); }
- try!(write!(f, "{}: {}", *k, *v));
- }
-
- write!(f, "}}")
- }
-}
-
-impl<K: Ord, V> Default for TreeMap<K,V> {
- #[inline]
- fn default() -> TreeMap<K, V> { TreeMap::new() }
-}
-
-impl<K: Ord, V> Index<K, V> for TreeMap<K, V> {
- #[inline]
- fn index<'a>(&'a self, i: &K) -> &'a V {
- self.find(i).expect("no entry found for key")
- }
-}
-
-impl<K: Ord, V> IndexMut<K, V> for TreeMap<K, V> {
- #[inline]
- fn index_mut<'a>(&'a mut self, i: &K) -> &'a mut V {
- self.find_mut(i).expect("no entry found for key")
- }
-}
-
-impl<K: Ord, V> TreeMap<K, V> {
- /// Creates an empty `TreeMap`.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- /// let mut map: TreeMap<&str, int> = TreeMap::new();
- /// ```
- pub fn new() -> TreeMap<K, V> { TreeMap{root: None, length: 0} }
-
- /// Gets a lazy iterator over the keys in the map, in ascending order.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- /// let mut map = TreeMap::new();
- /// map.insert("a", 1i);
- /// map.insert("c", 3i);
- /// map.insert("b", 2i);
- ///
- /// // Print "a", "b", "c" in order.
- /// for x in map.keys() {
- /// println!("{}", x);
- /// }
- /// ```
- pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
- self.iter().map(|(k, _v)| k)
- }
-
- /// Gets a lazy iterator over the values in the map, in ascending order
- /// with respect to the corresponding keys.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- /// let mut map = TreeMap::new();
- /// map.insert("a", 1i);
- /// map.insert("c", 3i);
- /// map.insert("b", 2i);
- ///
- /// // Print 1, 2, 3 ordered by keys.
- /// for x in map.values() {
- /// println!("{}", x);
- /// }
- /// ```
- pub fn values<'a>(&'a self) -> Values<'a, K, V> {
- self.iter().map(|(_k, v)| v)
- }
-
- /// Gets a lazy iterator over the key-value pairs in the map, in ascending order.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- /// let mut map = TreeMap::new();
- /// map.insert("a", 1i);
- /// map.insert("c", 3i);
- /// map.insert("b", 2i);
- ///
- /// // Print contents in ascending order
- /// for (key, value) in map.iter() {
- /// println!("{}: {}", key, value);
- /// }
- /// ```
- pub fn iter<'a>(&'a self) -> Entries<'a, K, V> {
- Entries {
- stack: vec!(),
- node: deref(&self.root),
- remaining_min: self.length,
- remaining_max: self.length
- }
- }
-
- /// Gets a lazy reverse iterator over the key-value pairs in the map, in descending order.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- /// let mut map = TreeMap::new();
- /// map.insert("a", 1i);
- /// map.insert("c", 3i);
- /// map.insert("b", 2i);
- ///
- /// // Print contents in descending order
- /// for (key, value) in map.rev_iter() {
- /// println!("{}: {}", key, value);
- /// }
- /// ```
- pub fn rev_iter<'a>(&'a self) -> RevEntries<'a, K, V> {
- RevEntries{iter: self.iter()}
- }
-
- /// Gets a lazy forward iterator over the key-value pairs in the
- /// map, with the values being mutable.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- /// let mut map = TreeMap::new();
- /// map.insert("a", 1i);
- /// map.insert("c", 3i);
- /// map.insert("b", 2i);
- ///
- /// // Add 10 until we find "b"
- /// for (key, value) in map.iter_mut() {
- /// *value += 10;
- /// if key == &"b" { break }
- /// }
- ///
- /// assert_eq!(map.find(&"a"), Some(&11));
- /// assert_eq!(map.find(&"b"), Some(&12));
- /// assert_eq!(map.find(&"c"), Some(&3));
- /// ```
- pub fn iter_mut<'a>(&'a mut self) -> MutEntries<'a, K, V> {
- MutEntries {
- stack: vec!(),
- node: deref_mut(&mut self.root),
- remaining_min: self.length,
- remaining_max: self.length
- }
- }
-
- /// Gets a lazy reverse iterator over the key-value pairs in the
- /// map, with the values being mutable.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- /// let mut map = TreeMap::new();
- /// map.insert("a", 1i);
- /// map.insert("c", 3i);
- /// map.insert("b", 2i);
- ///
- /// // Add 10 until we find "b"
- /// for (key, value) in map.rev_iter_mut() {
- /// *value += 10;
- /// if key == &"b" { break }
- /// }
- ///
- /// assert_eq!(map.find(&"a"), Some(&1));
- /// assert_eq!(map.find(&"b"), Some(&12));
- /// assert_eq!(map.find(&"c"), Some(&13));
- /// ```
- pub fn rev_iter_mut<'a>(&'a mut self) -> RevMutEntries<'a, K, V> {
- RevMutEntries{iter: self.iter_mut()}
- }
-
- /// Gets a lazy iterator that consumes the treemap.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- /// let mut map = TreeMap::new();
- /// map.insert("a", 1i);
- /// map.insert("c", 3i);
- /// map.insert("b", 2i);
- ///
- /// // Not possible with a regular `.iter()`
- /// let vec: Vec<(&str, int)> = map.into_iter().collect();
- /// assert_eq!(vec, vec![("a", 1), ("b", 2), ("c", 3)]);
- /// ```
- pub fn into_iter(self) -> MoveEntries<K, V> {
- let TreeMap { root, length } = self;
- let stk = match root {
- None => vec!(),
- Some(box tn) => vec!(tn)
- };
- MoveEntries {
- stack: stk,
- remaining: length
- }
- }
-
- /// Return the number of elements in the map.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- ///
- /// let mut a = TreeMap::new();
- /// assert_eq!(a.len(), 0);
- /// a.insert(1u, "a");
- /// assert_eq!(a.len(), 1);
- /// ```
- pub fn len(&self) -> uint { self.length }
-
- /// Return true if the map contains no elements.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- ///
- /// let mut a = TreeMap::new();
- /// assert!(a.is_empty());
- /// a.insert(1u, "a");
- /// assert!(!a.is_empty());
- /// ```
- #[inline]
- pub fn is_empty(&self) -> bool { self.len() == 0 }
-
- /// Clears the map, removing all values.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- ///
- /// let mut a = TreeMap::new();
- /// a.insert(1u, "a");
- /// a.clear();
- /// assert!(a.is_empty());
- /// ```
- pub fn clear(&mut self) {
- self.root = None;
- self.length = 0
- }
-
- /// Returns a reference to the value corresponding to the key.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- ///
- /// let mut map = TreeMap::new();
- /// map.insert(1u, "a");
- /// assert_eq!(map.find(&1), Some(&"a"));
- /// assert_eq!(map.find(&2), None);
- /// ```
- #[inline]
- pub fn find<'a>(&'a self, key: &K) -> Option<&'a V> {
- tree_find_with(&self.root, |k2| key.cmp(k2))
- }
-
- /// Returns true if the map contains a value for the specified key.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- ///
- /// let mut map = TreeMap::new();
- /// map.insert(1u, "a");
- /// assert_eq!(map.contains_key(&1), true);
- /// assert_eq!(map.contains_key(&2), false);
- /// ```
- #[inline]
- pub fn contains_key(&self, key: &K) -> bool {
- self.find(key).is_some()
- }
-
- /// Returns a mutable reference to the value corresponding to the key.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- ///
- /// let mut map = TreeMap::new();
- /// map.insert(1u, "a");
- /// match map.find_mut(&1) {
- /// Some(x) => *x = "b",
- /// None => (),
- /// }
- /// assert_eq!(map[1], "b");
- /// ```
- #[inline]
- pub fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> {
- tree_find_with_mut(&mut self.root, |x| key.cmp(x))
- }
-
- /// Inserts a key-value pair into the map. An existing value for a
- /// key is replaced by the new value. Returns `true` if the key did
- /// not already exist in the map.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- ///
- /// let mut map = TreeMap::new();
- /// assert_eq!(map.insert(2u, "value"), true);
- /// assert_eq!(map.insert(2, "value2"), false);
- /// assert_eq!(map[2], "value2");
- /// ```
- #[inline]
- pub fn insert(&mut self, key: K, value: V) -> bool {
- self.swap(key, value).is_none()
- }
-
- /// Removes a key-value pair from the map. Returns `true` if the key
- /// was present in the map.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- ///
- /// let mut map = TreeMap::new();
- /// assert_eq!(map.remove(&1u), false);
- /// map.insert(1, "a");
- /// assert_eq!(map.remove(&1), true);
- /// ```
- #[inline]
- pub fn remove(&mut self, key: &K) -> bool {
- self.pop(key).is_some()
- }
-
- /// Inserts a key-value pair from the map. If the key already had a value
- /// present in the map, that value is returned. Otherwise, `None` is returned.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- ///
- /// let mut map = TreeMap::new();
- /// assert_eq!(map.swap(37u, "a"), None);
- /// assert_eq!(map.is_empty(), false);
- ///
- /// map.insert(37, "b");
- /// assert_eq!(map.swap(37, "c"), Some("b"));
- /// assert_eq!(map[37], "c");
- /// ```
- pub fn swap(&mut self, key: K, value: V) -> Option<V> {
- let ret = insert(&mut self.root, key, value);
- 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.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- ///
- /// let mut map = TreeMap::new();
- /// map.insert(1u, "a");
- /// assert_eq!(map.pop(&1), Some("a"));
- /// assert_eq!(map.pop(&1), None);
- /// ```
- pub fn pop(&mut self, key: &K) -> Option<V> {
- let ret = remove(&mut self.root, key);
- if ret.is_some() { self.length -= 1 }
- ret
- }
-}
-
-impl<K, V> TreeMap<K, V> {
- /// Returns the value for which `f(key)` returns `Equal`. `f` is invoked
- /// with current key and guides tree navigation. That means `f` should
- /// be aware of natural ordering of the tree.
- ///
- /// # Example
- ///
- /// ```
- /// use collections::treemap::TreeMap;
- ///
- /// fn get_headers() -> TreeMap<String, String> {
- /// let mut result = TreeMap::new();
- /// result.insert("Content-Type".to_string(), "application/xml".to_string());
- /// result.insert("User-Agent".to_string(), "Curl-Rust/0.1".to_string());
- /// result
- /// }
- ///
- /// let headers = get_headers();
- /// let ua_key = "User-Agent";
- /// let ua = headers.find_with(|k| {
- /// ua_key.cmp(&k.as_slice())
- /// });
- ///
- /// assert_eq!((*ua.unwrap()).as_slice(), "Curl-Rust/0.1");
- /// ```
- #[inline]
- pub fn find_with<'a>(&'a self, f:|&K| -> Ordering) -> Option<&'a V> {
- tree_find_with(&self.root, f)
- }
-
- /// Returns the value for which `f(key)` returns `Equal`. `f` is invoked
- /// with current key and guides tree navigation. That means `f` should
- /// be aware of natural ordering of the tree.
- ///
- /// # Example
- ///
- /// ```
- /// let mut t = collections::treemap::TreeMap::new();
- /// t.insert("Content-Type", "application/xml");
- /// t.insert("User-Agent", "Curl-Rust/0.1");
- ///
- /// let new_ua = "Safari/156.0";
- /// match t.find_with_mut(|k| "User-Agent".cmp(k)) {
- /// Some(x) => *x = new_ua,
- /// None => panic!(),
- /// }
- ///
- /// assert_eq!(t.find(&"User-Agent"), Some(&new_ua));
- /// ```
- #[inline]
- pub fn find_with_mut<'a>(&'a mut self, f:|&K| -> Ordering) -> Option<&'a mut V> {
- tree_find_with_mut(&mut self.root, f)
- }
-}
-
-// range iterators.
-
-macro_rules! bound_setup {
- // initialiser of the iterator to manipulate
- ($iter:expr, $k:expr,
- // whether we are looking for the lower or upper bound.
- $is_lower_bound:expr) => {
- {
- let mut iter = $iter;
- loop {
- if !iter.node.is_null() {
- let node_k = unsafe {&(*iter.node).key};
- match $k.cmp(node_k) {
- Less => iter.traverse_left(),
- Greater => iter.traverse_right(),
- Equal => {
- if $is_lower_bound {
- iter.traverse_complete();
- return iter;
- } else {
- iter.traverse_right()
- }
- }
- }
- } else {
- iter.traverse_complete();
- return iter;
- }
- }
- }
- }
-}
-
-
-impl<K: Ord, V> TreeMap<K, V> {
- /// Gets a lazy iterator that should be initialized using
- /// `traverse_left`/`traverse_right`/`traverse_complete`.
- fn iter_for_traversal<'a>(&'a self) -> Entries<'a, K, V> {
- Entries {
- stack: vec!(),
- node: deref(&self.root),
- remaining_min: 0,
- remaining_max: self.length
- }
- }
-
- /// Returns a lazy iterator to the first key-value pair whose key is not less than `k`
- /// If all keys in map are less than `k` an empty iterator is returned.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- ///
- /// let mut map = TreeMap::new();
- /// map.insert(2i, "a");
- /// map.insert(4, "b");
- /// map.insert(6, "c");
- /// map.insert(8, "d");
- ///
- /// assert_eq!(map.lower_bound(&4).next(), Some((&4, &"b")));
- /// assert_eq!(map.lower_bound(&5).next(), Some((&6, &"c")));
- /// assert_eq!(map.lower_bound(&10).next(), None);
- /// ```
- pub fn lower_bound<'a>(&'a self, k: &K) -> Entries<'a, K, V> {
- bound_setup!(self.iter_for_traversal(), k, true)
- }
-
- /// Returns a lazy iterator to the first key-value pair whose key is greater than `k`
- /// If all keys in map are less than or equal to `k` an empty iterator is returned.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- ///
- /// let mut map = TreeMap::new();
- /// map.insert(2i, "a");
- /// map.insert(4, "b");
- /// map.insert(6, "c");
- /// map.insert(8, "d");
- ///
- /// assert_eq!(map.upper_bound(&4).next(), Some((&6, &"c")));
- /// assert_eq!(map.upper_bound(&5).next(), Some((&6, &"c")));
- /// assert_eq!(map.upper_bound(&10).next(), None);
- /// ```
- pub fn upper_bound<'a>(&'a self, k: &K) -> Entries<'a, K, V> {
- bound_setup!(self.iter_for_traversal(), k, false)
- }
-
- /// Gets a lazy iterator that should be initialized using
- /// `traverse_left`/`traverse_right`/`traverse_complete`.
- fn iter_mut_for_traversal<'a>(&'a mut self) -> MutEntries<'a, K, V> {
- MutEntries {
- stack: vec!(),
- node: deref_mut(&mut self.root),
- remaining_min: 0,
- remaining_max: self.length
- }
- }
-
- /// Returns a lazy value iterator to the first key-value pair (with
- /// the value being mutable) whose key is not less than `k`.
- ///
- /// If all keys in map are less than `k` an empty iterator is
- /// returned.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- ///
- /// let mut map = TreeMap::new();
- /// map.insert(2i, "a");
- /// map.insert(4, "b");
- /// map.insert(6, "c");
- /// map.insert(8, "d");
- ///
- /// assert_eq!(map.lower_bound_mut(&4).next(), Some((&4, &mut "b")));
- /// assert_eq!(map.lower_bound_mut(&5).next(), Some((&6, &mut "c")));
- /// assert_eq!(map.lower_bound_mut(&10).next(), None);
- ///
- /// for (key, value) in map.lower_bound_mut(&4) {
- /// *value = "changed";
- /// }
- ///
- /// assert_eq!(map.find(&2), Some(&"a"));
- /// assert_eq!(map.find(&4), Some(&"changed"));
- /// assert_eq!(map.find(&6), Some(&"changed"));
- /// assert_eq!(map.find(&8), Some(&"changed"));
- /// ```
- pub fn lower_bound_mut<'a>(&'a mut self, k: &K) -> MutEntries<'a, K, V> {
- bound_setup!(self.iter_mut_for_traversal(), k, true)
- }
-
- /// Returns a lazy iterator to the first key-value pair (with the
- /// value being mutable) whose key is greater than `k`.
- ///
- /// If all keys in map are less than or equal to `k` an empty iterator
- /// is returned.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeMap;
- ///
- /// let mut map = TreeMap::new();
- /// map.insert(2i, "a");
- /// map.insert(4, "b");
- /// map.insert(6, "c");
- /// map.insert(8, "d");
- ///
- /// assert_eq!(map.upper_bound_mut(&4).next(), Some((&6, &mut "c")));
- /// assert_eq!(map.upper_bound_mut(&5).next(), Some((&6, &mut "c")));
- /// assert_eq!(map.upper_bound_mut(&10).next(), None);
- ///
- /// for (key, value) in map.upper_bound_mut(&4) {
- /// *value = "changed";
- /// }
- ///
- /// assert_eq!(map.find(&2), Some(&"a"));
- /// assert_eq!(map.find(&4), Some(&"b"));
- /// assert_eq!(map.find(&6), Some(&"changed"));
- /// assert_eq!(map.find(&8), Some(&"changed"));
- /// ```
- pub fn upper_bound_mut<'a>(&'a mut self, k: &K) -> MutEntries<'a, K, V> {
- bound_setup!(self.iter_mut_for_traversal(), k, false)
- }
-}
-
-/// Lazy forward iterator over a map
-pub struct Entries<'a, K:'a, V:'a> {
- stack: Vec<&'a TreeNode<K, V>>,
- // See the comment on MutEntries; this is just to allow
- // code-sharing (for this immutable-values iterator it *could* very
- // well be Option<&'a TreeNode<K,V>>).
- node: *const TreeNode<K, V>,
- remaining_min: uint,
- remaining_max: uint
-}
-
-/// Lazy backward iterator over a map
-pub struct RevEntries<'a, K:'a, V:'a> {
- iter: Entries<'a, K, V>,
-}
-
-/// Lazy forward iterator over a map that allows for the mutation of
-/// the values.
-pub struct MutEntries<'a, K:'a, V:'a> {
- stack: Vec<&'a mut TreeNode<K, V>>,
- // Unfortunately, we require some unsafe-ness to get around the
- // fact that we would be storing a reference *into* one of the
- // nodes in the stack.
- //
- // As far as the compiler knows, this would let us invalidate the
- // reference by assigning a new value to this node's position in
- // its parent, which would cause this current one to be
- // deallocated so this reference would be invalid. (i.e. the
- // compilers complaints are 100% correct.)
- //
- // However, as far as you humans reading this code know (or are
- // about to know, if you haven't read far enough down yet), we are
- // only reading from the TreeNode.{left,right} fields. the only
- // thing that is ever mutated is the .value field (although any
- // actual mutation that happens is done externally, by the
- // iterator consumer). So, don't be so concerned, rustc, we've got
- // it under control.
- //
- // (This field can legitimately be null.)
- node: *mut TreeNode<K, V>,
- remaining_min: uint,
- remaining_max: uint
-}
-
-/// Lazy backward iterator over a map
-pub struct RevMutEntries<'a, K:'a, V:'a> {
- iter: MutEntries<'a, K, V>,
-}
-
-/// TreeMap keys iterator.
-pub type Keys<'a, K, V> =
- iter::Map<'static, (&'a K, &'a V), &'a K, Entries<'a, K, V>>;
-
-/// TreeMap values iterator.
-pub type Values<'a, K, V> =
- iter::Map<'static, (&'a K, &'a V), &'a V, Entries<'a, K, V>>;
-
-
-// FIXME #5846 we want to be able to choose between &x and &mut x
-// (with many different `x`) below, so we need to optionally pass mut
-// as a tt, but the only thing we can do with a `tt` is pass them to
-// other macros, so this takes the `& <mutability> <operand>` token
-// sequence and forces their evaluation as an expression.
-macro_rules! addr { ($e:expr) => { $e }}
-// putting an optional mut into type signatures
-macro_rules! item { ($i:item) => { $i }}
-
-macro_rules! define_iterator {
- ($name:ident,
- $rev_name:ident,
-
- // the function to go from &m Option<Box<TreeNode>> to *m TreeNode
- deref = $deref:ident,
-
- // see comment on `addr!`, this is just an optional `mut`, but
- // there's no support for 0-or-1 repeats.
- addr_mut = $($addr_mut:tt)*
- ) => {
- // private methods on the forward iterator (item!() for the
- // addr_mut in the next_ return value)
- item!(impl<'a, K, V> $name<'a, K, V> {
- #[inline(always)]
- fn next_(&mut self, forward: bool) -> Option<(&'a K, &'a $($addr_mut)* V)> {
- while !self.stack.is_empty() || !self.node.is_null() {
- if !self.node.is_null() {
- let node = unsafe {addr!(& $($addr_mut)* *self.node)};
- {
- let next_node = if forward {
- addr!(& $($addr_mut)* node.left)
- } else {
- addr!(& $($addr_mut)* node.right)
- };
- self.node = $deref(next_node);
- }
- self.stack.push(node);
- } else {
- let node = self.stack.pop().unwrap();
- let next_node = if forward {
- addr!(& $($addr_mut)* node.right)
- } else {
- addr!(& $($addr_mut)* node.left)
- };
- self.node = $deref(next_node);
- self.remaining_max -= 1;
- if self.remaining_min > 0 {
- self.remaining_min -= 1;
- }
- return Some((&node.key, addr!(& $($addr_mut)* node.value)));
- }
- }
- None
- }
-
- /// traverse_left, traverse_right and traverse_complete are
- /// used to initialize Entries/MutEntries
- /// pointing to element inside tree structure.
- ///
- /// They should be used in following manner:
- /// - create iterator using TreeMap::[mut_]iter_for_traversal
- /// - find required node using `traverse_left`/`traverse_right`
- /// (current node is `Entries::node` field)
- /// - complete initialization with `traverse_complete`
- ///
- /// After this, iteration will start from `self.node`. If
- /// `self.node` is None iteration will start from last
- /// node from which we traversed left.
- #[inline]
- fn traverse_left(&mut self) {
- let node = unsafe {addr!(& $($addr_mut)* *self.node)};
- self.node = $deref(addr!(& $($addr_mut)* node.left));
- self.stack.push(node);
- }
-
- #[inline]
- fn traverse_right(&mut self) {
- let node = unsafe {addr!(& $($addr_mut)* *self.node)};
- self.node = $deref(addr!(& $($addr_mut)* node.right));
- }
-
- #[inline]
- fn traverse_complete(&mut self) {
- if !self.node.is_null() {
- unsafe {
- self.stack.push(addr!(& $($addr_mut)* *self.node));
- }
- self.node = ptr::RawPtr::null();
- }
- }
- })
-
- // the forward Iterator impl.
- item!(impl<'a, K, V> Iterator<(&'a K, &'a $($addr_mut)* V)> for $name<'a, K, V> {
- /// Advances the iterator to the next node (in order) and return a
- /// tuple with a reference to the key and value. If there are no
- /// more nodes, return `None`.
- fn next(&mut self) -> Option<(&'a K, &'a $($addr_mut)* V)> {
- self.next_(true)
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- (self.remaining_min, Some(self.remaining_max))
- }
- })
-
- // the reverse Iterator impl.
- item!(impl<'a, K, V> Iterator<(&'a K, &'a $($addr_mut)* V)> for $rev_name<'a, K, V> {
- fn next(&mut self) -> Option<(&'a K, &'a $($addr_mut)* V)> {
- self.iter.next_(false)
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- self.iter.size_hint()
- }
- })
- }
-} // end of define_iterator
-
-define_iterator! {
- Entries,
- RevEntries,
- deref = deref,
-
- // immutable, so no mut
- addr_mut =
-}
-define_iterator! {
- MutEntries,
- RevMutEntries,
- deref = deref_mut,
-
- addr_mut = mut
-}
-
-fn deref<'a, K, V>(node: &'a Option<Box<TreeNode<K, V>>>) -> *const TreeNode<K, V> {
- match *node {
- Some(ref n) => {
- let n: &TreeNode<K, V> = &**n;
- n as *const TreeNode<K, V>
- }
- None => ptr::null()
- }
-}
-
-fn deref_mut<K, V>(x: &mut Option<Box<TreeNode<K, V>>>)
- -> *mut TreeNode<K, V> {
- match *x {
- Some(ref mut n) => {
- let n: &mut TreeNode<K, V> = &mut **n;
- n as *mut TreeNode<K, V>
- }
- None => ptr::null_mut()
- }
-}
-
-/// Lazy forward iterator over a map that consumes the map while iterating
-pub struct MoveEntries<K, V> {
- stack: Vec<TreeNode<K, V>>,
- remaining: uint
-}
-
-impl<K, V> Iterator<(K, V)> for MoveEntries<K,V> {
- #[inline]
- fn next(&mut self) -> Option<(K, V)> {
- while !self.stack.is_empty() {
- let TreeNode {
- key,
- value,
- left,
- right,
- level,
- } = self.stack.pop().unwrap();
-
- match left {
- Some(box left) => {
- let n = TreeNode {
- key: key,
- value: value,
- left: None,
- right: right,
- level: level
- };
- self.stack.push(n);
- self.stack.push(left);
- }
- None => {
- match right {
- Some(box right) => self.stack.push(right),
- None => ()
- }
- self.remaining -= 1;
- return Some((key, value))
- }
- }
- }
- None
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- (self.remaining, Some(self.remaining))
- }
-
-}
-
-impl<'a, T> Iterator<&'a T> for SetItems<'a, T> {
- #[inline]
- fn next(&mut self) -> Option<&'a T> {
- self.iter.next().map(|(value, _)| value)
- }
-}
-
-impl<'a, T> Iterator<&'a T> for RevSetItems<'a, T> {
- #[inline]
- fn next(&mut self) -> Option<&'a T> {
- self.iter.next().map(|(value, _)| value)
- }
-}
-
-/// An implementation of the `Set` trait on top of the `TreeMap` container. The
-/// only requirement is that the type of the elements contained ascribes to the
-/// `Ord` trait.
-///
-/// ## Example
-///
-/// ```{rust}
-/// use std::collections::TreeSet;
-///
-/// let mut set = TreeSet::new();
-///
-/// set.insert(2i);
-/// set.insert(1i);
-/// set.insert(3i);
-///
-/// for i in set.iter() {
-/// println!("{}", i) // prints 1, then 2, then 3
-/// }
-///
-/// set.remove(&3);
-///
-/// if !set.contains(&3) {
-/// println!("set does not contain a 3 anymore");
-/// }
-/// ```
-///
-/// The easiest way to use `TreeSet` with a custom type is to implement `Ord`.
-/// We must also implement `PartialEq`, `Eq` and `PartialOrd`.
-///
-/// ```
-/// use std::collections::TreeSet;
-///
-/// // We need `Eq` and `PartialEq`, these can be derived.
-/// #[deriving(Eq, PartialEq)]
-/// struct Troll<'a> {
-/// name: &'a str,
-/// level: uint,
-/// }
-///
-/// // Implement `Ord` and sort trolls by level.
-/// impl<'a> Ord for Troll<'a> {
-/// fn cmp(&self, other: &Troll) -> Ordering {
-/// // If we swap `self` and `other`, we get descending ordering.
-/// self.level.cmp(&other.level)
-/// }
-/// }
-///
-/// // `PartialOrd` needs to be implemented as well.
-/// impl<'a> PartialOrd for Troll<'a> {
-/// fn partial_cmp(&self, other: &Troll) -> Option<Ordering> {
-/// Some(self.cmp(other))
-/// }
-/// }
-///
-/// let mut trolls = TreeSet::new();
-///
-/// trolls.insert(Troll { name: "Orgarr", level: 2 });
-/// trolls.insert(Troll { name: "Blargarr", level: 3 });
-/// trolls.insert(Troll { name: "Kron the Smelly One", level: 4 });
-/// trolls.insert(Troll { name: "Wartilda", level: 1 });
-///
-/// println!("You are facing {} trolls!", trolls.len());
-///
-/// // Print the trolls, ordered by level with smallest level first
-/// for x in trolls.iter() {
-/// println!("level {}: {}!", x.level, x.name);
-/// }
-///
-/// // Kill all trolls
-/// trolls.clear();
-/// assert_eq!(trolls.len(), 0);
-/// ```
-#[deriving(Clone)]
-pub struct TreeSet<T> {
- map: TreeMap<T, ()>
-}
-
-impl<T: PartialEq + Ord> PartialEq for TreeSet<T> {
- #[inline]
- fn eq(&self, other: &TreeSet<T>) -> bool { self.map == other.map }
-}
-
-impl<T: Eq + Ord> Eq for TreeSet<T> {}
-
-impl<T: Ord> PartialOrd for TreeSet<T> {
- #[inline]
- fn partial_cmp(&self, other: &TreeSet<T>) -> Option<Ordering> {
- self.map.partial_cmp(&other.map)
- }
-}
-
-impl<T: Ord> Ord for TreeSet<T> {
- #[inline]
- fn cmp(&self, other: &TreeSet<T>) -> Ordering {
- iter::order::cmp(self.iter(), other.iter())
- }
-}
-
-impl<T: Ord + Show> Show for TreeSet<T> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- try!(write!(f, "{{"));
-
- for (i, x) in self.iter().enumerate() {
- if i != 0 { try!(write!(f, ", ")); }
- try!(write!(f, "{}", *x));
- }
-
- write!(f, "}}")
- }
-}
-
-impl<T: Ord> Default for TreeSet<T> {
- #[inline]
- fn default() -> TreeSet<T> { TreeSet::new() }
-}
-
-impl<T: Ord> TreeSet<T> {
- /// Creates an empty `TreeSet`.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeSet;
- /// let mut set: TreeSet<int> = TreeSet::new();
- /// ```
- #[inline]
- pub fn new() -> TreeSet<T> { TreeSet{map: TreeMap::new()} }
-
- /// Gets a lazy iterator over the values in the set, in ascending order.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeSet;
- /// let set: TreeSet<int> = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect();
- ///
- /// // Will print in ascending order.
- /// for x in set.iter() {
- /// println!("{}", x);
- /// }
- /// ```
- #[inline]
- pub fn iter<'a>(&'a self) -> SetItems<'a, T> {
- SetItems{iter: self.map.iter()}
- }
-
- /// Gets a lazy iterator over the values in the set, in descending order.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeSet;
- /// let set: TreeSet<int> = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect();
- ///
- /// // Will print in descending order.
- /// for x in set.rev_iter() {
- /// println!("{}", x);
- /// }
- /// ```
- #[inline]
- pub fn rev_iter<'a>(&'a self) -> RevSetItems<'a, T> {
- RevSetItems{iter: self.map.rev_iter()}
- }
-
- /// Creates a consuming iterator, that is, one that moves each value out of the
- /// set in ascending order. The set cannot be used after calling this.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeSet;
- /// let set: TreeSet<int> = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect();
- ///
- /// // Not possible with a regular `.iter()`
- /// let v: Vec<int> = set.into_iter().collect();
- /// assert_eq!(v, vec![1, 2, 3, 4, 5]);
- /// ```
- #[inline]
- pub fn into_iter(self) -> MoveSetItems<T> {
- self.map.into_iter().map(|(value, _)| value)
- }
-
- /// Gets a lazy iterator pointing to the first value not less than `v` (greater or equal).
- /// If all elements in the set are less than `v` empty iterator is returned.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeSet;
- /// let set: TreeSet<int> = [2, 4, 6, 8].iter().map(|&x| x).collect();
- ///
- /// assert_eq!(set.lower_bound(&4).next(), Some(&4));
- /// assert_eq!(set.lower_bound(&5).next(), Some(&6));
- /// assert_eq!(set.lower_bound(&10).next(), None);
- /// ```
- #[inline]
- pub fn lower_bound<'a>(&'a self, v: &T) -> SetItems<'a, T> {
- SetItems{iter: self.map.lower_bound(v)}
- }
-
- /// Gets a lazy iterator pointing to the first value greater than `v`.
- /// If all elements in the set are less than or equal to `v` an
- /// empty iterator is returned.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeSet;
- /// let set: TreeSet<int> = [2, 4, 6, 8].iter().map(|&x| x).collect();
- ///
- /// assert_eq!(set.upper_bound(&4).next(), Some(&6));
- /// assert_eq!(set.upper_bound(&5).next(), Some(&6));
- /// assert_eq!(set.upper_bound(&10).next(), None);
- /// ```
- #[inline]
- pub fn upper_bound<'a>(&'a self, v: &T) -> SetItems<'a, T> {
- SetItems{iter: self.map.upper_bound(v)}
- }
-
- /// Visits the values representing the difference, in ascending order.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeSet;
- ///
- /// let a: TreeSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
- /// let b: TreeSet<int> = [3, 4, 5].iter().map(|&x| x).collect();
- ///
- /// // Can be seen as `a - b`.
- /// for x in a.difference(&b) {
- /// println!("{}", x); // Print 1 then 2
- /// }
- ///
- /// let diff: TreeSet<int> = a.difference(&b).map(|&x| x).collect();
- /// assert_eq!(diff, [1, 2].iter().map(|&x| x).collect());
- ///
- /// // Note that difference is not symmetric,
- /// // and `b - a` means something else:
- /// let diff: TreeSet<int> = b.difference(&a).map(|&x| x).collect();
- /// assert_eq!(diff, [4, 5].iter().map(|&x| x).collect());
- /// ```
- pub fn difference<'a>(&'a self, other: &'a TreeSet<T>) -> DifferenceItems<'a, T> {
- DifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()}
- }
-
- /// Visits the values representing the symmetric difference, in ascending order.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeSet;
- ///
- /// let a: TreeSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
- /// let b: TreeSet<int> = [3, 4, 5].iter().map(|&x| x).collect();
- ///
- /// // Print 1, 2, 4, 5 in ascending order.
- /// for x in a.symmetric_difference(&b) {
- /// println!("{}", x);
- /// }
- ///
- /// let diff1: TreeSet<int> = a.symmetric_difference(&b).map(|&x| x).collect();
- /// let diff2: TreeSet<int> = b.symmetric_difference(&a).map(|&x| x).collect();
- ///
- /// assert_eq!(diff1, diff2);
- /// assert_eq!(diff1, [1, 2, 4, 5].iter().map(|&x| x).collect());
- /// ```
- pub fn symmetric_difference<'a>(&'a self, other: &'a TreeSet<T>)
- -> SymDifferenceItems<'a, T> {
- SymDifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()}
- }
-
- /// Visits the values representing the intersection, in ascending order.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeSet;
- ///
- /// let a: TreeSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
- /// let b: TreeSet<int> = [2, 3, 4].iter().map(|&x| x).collect();
- ///
- /// // Print 2, 3 in ascending order.
- /// for x in a.intersection(&b) {
- /// println!("{}", x);
- /// }
- ///
- /// let diff: TreeSet<int> = a.intersection(&b).map(|&x| x).collect();
- /// assert_eq!(diff, [2, 3].iter().map(|&x| x).collect());
- /// ```
- pub fn intersection<'a>(&'a self, other: &'a TreeSet<T>)
- -> IntersectionItems<'a, T> {
- IntersectionItems{a: self.iter().peekable(), b: other.iter().peekable()}
- }
-
- /// Visits the values representing the union, in ascending order.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeSet;
- ///
- /// let a: TreeSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
- /// let b: TreeSet<int> = [3, 4, 5].iter().map(|&x| x).collect();
- ///
- /// // Print 1, 2, 3, 4, 5 in ascending order.
- /// for x in a.union(&b) {
- /// println!("{}", x);
- /// }
- ///
- /// let diff: TreeSet<int> = a.union(&b).map(|&x| x).collect();
- /// assert_eq!(diff, [1, 2, 3, 4, 5].iter().map(|&x| x).collect());
- /// ```
- pub fn union<'a>(&'a self, other: &'a TreeSet<T>) -> UnionItems<'a, T> {
- UnionItems{a: self.iter().peekable(), b: other.iter().peekable()}
- }
-
- /// Return the number of elements in the set
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeSet;
- ///
- /// let mut v = TreeSet::new();
- /// assert_eq!(v.len(), 0);
- /// v.insert(1i);
- /// assert_eq!(v.len(), 1);
- /// ```
- #[inline]
- pub fn len(&self) -> uint { self.map.len() }
-
- /// Returns true if the set contains no elements
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeSet;
- ///
- /// let mut v = TreeSet::new();
- /// assert!(v.is_empty());
- /// v.insert(1i);
- /// assert!(!v.is_empty());
- /// ```
- pub fn is_empty(&self) -> bool { self.len() == 0 }
-
- /// Clears the set, removing all values.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeSet;
- ///
- /// let mut v = TreeSet::new();
- /// v.insert(1i);
- /// v.clear();
- /// assert!(v.is_empty());
- /// ```
- #[inline]
- pub fn clear(&mut self) { self.map.clear() }
-
- /// Returns `true` if the set contains a value.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeSet;
- ///
- /// let set: TreeSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
- /// assert_eq!(set.contains(&1), true);
- /// assert_eq!(set.contains(&4), false);
- /// ```
- #[inline]
- pub fn contains(&self, value: &T) -> bool {
- self.map.contains_key(value)
- }
-
- /// Returns `true` if the set has no elements in common with `other`.
- /// This is equivalent to checking for an empty intersection.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeSet;
- ///
- /// let a: TreeSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
- /// let mut b: TreeSet<int> = TreeSet::new();
- ///
- /// assert_eq!(a.is_disjoint(&b), true);
- /// b.insert(4);
- /// assert_eq!(a.is_disjoint(&b), true);
- /// b.insert(1);
- /// assert_eq!(a.is_disjoint(&b), false);
- /// ```
- pub fn is_disjoint(&self, other: &TreeSet<T>) -> bool {
- self.intersection(other).next().is_none()
- }
-
- /// Returns `true` if the set is a subset of another.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeSet;
- ///
- /// let sup: TreeSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
- /// let mut set: TreeSet<int> = TreeSet::new();
- ///
- /// assert_eq!(set.is_subset(&sup), true);
- /// set.insert(2);
- /// assert_eq!(set.is_subset(&sup), true);
- /// set.insert(4);
- /// assert_eq!(set.is_subset(&sup), false);
- /// ```
- pub fn is_subset(&self, other: &TreeSet<T>) -> bool {
- let mut x = self.iter();
- let mut y = other.iter();
- let mut a = x.next();
- let mut b = y.next();
- while a.is_some() {
- if b.is_none() {
- return false;
- }
-
- let a1 = a.unwrap();
- let b1 = b.unwrap();
-
- match b1.cmp(a1) {
- Less => (),
- Greater => return false,
- Equal => a = x.next(),
- }
-
- b = y.next();
- }
- true
- }
-
- /// Returns `true` if the set is a superset of another.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TreeSet;
- ///
- /// let sub: TreeSet<int> = [1i, 2].iter().map(|&x| x).collect();
- /// let mut set: TreeSet<int> = TreeSet::new();
- ///
- /// assert_eq!(set.is_superset(&sub), false);
- ///
- /// set.insert(0);
- /// set.insert(1);
- /// assert_eq!(set.is_superset(&sub), false);
- ///
- /// set.insert(2);
- /// assert_eq!(set.is_superset(&sub), true);
- /// ```
- pub fn is_superset(&self, other: &TreeSet<T>) -> bool {
- other.is_subset(self)
- }
-
- /// Adds a value to the set. Returns `true` if the value was not already
- /// present in the set.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::BTreeSet;
- ///
- /// let mut set = BTreeSet::new();
- ///
- /// assert_eq!(set.insert(2i), true);
- /// assert_eq!(set.insert(2i), false);
- /// assert_eq!(set.len(), 1);
- /// ```
- #[inline]
- pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
-
- /// Removes a value from the set. Returns `true` if the value was
- /// present in the set.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::BTreeSet;
- ///
- /// let mut set = BTreeSet::new();
- ///
- /// set.insert(2i);
- /// assert_eq!(set.remove(&2), true);
- /// assert_eq!(set.remove(&2), false);
- /// ```
- #[inline]
- pub fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
-}
-
-/// A lazy forward iterator over a set.
-pub struct SetItems<'a, T:'a> {
- iter: Entries<'a, T, ()>
-}
-
-/// A lazy backward iterator over a set.
-pub struct RevSetItems<'a, T:'a> {
- iter: RevEntries<'a, T, ()>
-}
-
-/// A lazy forward iterator over a set that consumes the set while iterating.
-pub type MoveSetItems<T> = iter::Map<'static, (T, ()), T, MoveEntries<T, ()>>;
-
-/// A lazy iterator producing elements in the set difference (in-order).
-pub struct DifferenceItems<'a, T:'a> {
- a: Peekable<&'a T, SetItems<'a, T>>,
- b: Peekable<&'a T, SetItems<'a, T>>,
-}
-
-/// A lazy iterator producing elements in the set symmetric difference (in-order).
-pub struct SymDifferenceItems<'a, T:'a> {
- a: Peekable<&'a T, SetItems<'a, T>>,
- b: Peekable<&'a T, SetItems<'a, T>>,
-}
-
-/// A lazy iterator producing elements in the set intersection (in-order).
-pub struct IntersectionItems<'a, T:'a> {
- a: Peekable<&'a T, SetItems<'a, T>>,
- b: Peekable<&'a T, SetItems<'a, T>>,
-}
-
-/// A lazy iterator producing elements in the set union (in-order).
-pub struct UnionItems<'a, T:'a> {
- a: Peekable<&'a T, SetItems<'a, T>>,
- b: Peekable<&'a T, SetItems<'a, T>>,
-}
-
-/// Compare `x` and `y`, but return `short` if x is None and `long` if y is None
-fn cmp_opt<T: Ord>(x: Option<&T>, y: Option<&T>,
- short: Ordering, long: Ordering) -> Ordering {
- match (x, y) {
- (None , _ ) => short,
- (_ , None ) => long,
- (Some(x1), Some(y1)) => x1.cmp(y1),
- }
-}
-
-impl<'a, T: Ord> Iterator<&'a T> for DifferenceItems<'a, T> {
- fn next(&mut self) -> Option<&'a T> {
- loop {
- match cmp_opt(self.a.peek(), self.b.peek(), Less, Less) {
- Less => return self.a.next(),
- Equal => { self.a.next(); self.b.next(); }
- Greater => { self.b.next(); }
- }
- }
- }
-}
-
-impl<'a, T: Ord> Iterator<&'a T> for SymDifferenceItems<'a, T> {
- fn next(&mut self) -> Option<&'a T> {
- loop {
- match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) {
- Less => return self.a.next(),
- Equal => { self.a.next(); self.b.next(); }
- Greater => return self.b.next(),
- }
- }
- }
-}
-
-impl<'a, T: Ord> Iterator<&'a T> for IntersectionItems<'a, T> {
- fn next(&mut self) -> Option<&'a T> {
- loop {
- let o_cmp = match (self.a.peek(), self.b.peek()) {
- (None , _ ) => None,
- (_ , None ) => None,
- (Some(a1), Some(b1)) => Some(a1.cmp(b1)),
- };
- match o_cmp {
- None => return None,
- Some(Less) => { self.a.next(); }
- Some(Equal) => { self.b.next(); return self.a.next() }
- Some(Greater) => { self.b.next(); }
- }
- }
- }
-}
-
-impl<'a, T: Ord> Iterator<&'a T> for UnionItems<'a, T> {
- fn next(&mut self) -> Option<&'a T> {
- loop {
- match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) {
- Less => return self.a.next(),
- Equal => { self.b.next(); return self.a.next() }
- Greater => return self.b.next(),
- }
- }
- }
-}
-
-
-// Nodes keep track of their level in the tree, starting at 1 in the
-// leaves and with a red child sharing the level of the parent.
-#[deriving(Clone)]
-struct TreeNode<K, V> {
- key: K,
- value: V,
- left: Option<Box<TreeNode<K, V>>>,
- right: Option<Box<TreeNode<K, V>>>,
- level: uint
-}
-
-impl<K: Ord, V> TreeNode<K, V> {
- /// Creates a new tree node.
- #[inline]
- pub fn new(key: K, value: V) -> TreeNode<K, V> {
- TreeNode{key: key, value: value, left: None, right: None, level: 1}
- }
-}
-
-// Remove left horizontal link by rotating right
-fn skew<K: Ord, V>(node: &mut Box<TreeNode<K, V>>) {
- if node.left.as_ref().map_or(false, |x| x.level == node.level) {
- let mut save = node.left.take().unwrap();
- swap(&mut node.left, &mut save.right); // save.right now None
- swap(node, &mut save);
- node.right = Some(save);
- }
-}
-
-// Remove dual horizontal link by rotating left and increasing level of
-// the parent
-fn split<K: Ord, V>(node: &mut Box<TreeNode<K, V>>) {
- if node.right.as_ref().map_or(false,
- |x| x.right.as_ref().map_or(false, |y| y.level == node.level)) {
- let mut save = node.right.take().unwrap();
- swap(&mut node.right, &mut save.left); // save.left now None
- save.level += 1;
- swap(node, &mut save);
- node.left = Some(save);
- }
-}
-
-// Next 2 functions have the same convention: comparator gets
-// at input current key and returns search_key cmp cur_key
-// (i.e. search_key.cmp(&cur_key))
-fn tree_find_with<'r, K, V>(node: &'r Option<Box<TreeNode<K, V>>>,
- f: |&K| -> Ordering) -> Option<&'r V> {
- let mut current: &'r Option<Box<TreeNode<K, V>>> = node;
- loop {
- match *current {
- Some(ref r) => {
- match f(&r.key) {
- Less => current = &r.left,
- Greater => current = &r.right,
- Equal => return Some(&r.value)
- }
- }
- None => return None
- }
- }
-}
-
-// See comments above tree_find_with
-fn tree_find_with_mut<'r, K, V>(node: &'r mut Option<Box<TreeNode<K, V>>>,
- f: |&K| -> Ordering) -> Option<&'r mut V> {
-
- let mut current = node;
- loop {
- let temp = current; // hack to appease borrowck
- match *temp {
- Some(ref mut r) => {
- match f(&r.key) {
- Less => current = &mut r.left,
- Greater => current = &mut r.right,
- Equal => return Some(&mut r.value)
- }
- }
- None => return None
- }
- }
-}
-
-fn insert<K: Ord, V>(node: &mut Option<Box<TreeNode<K, V>>>,
- key: K, value: V) -> Option<V> {
- match *node {
- Some(ref mut save) => {
- match key.cmp(&save.key) {
- Less => {
- let inserted = insert(&mut save.left, key, value);
- skew(save);
- split(save);
- inserted
- }
- Greater => {
- let inserted = insert(&mut save.right, key, value);
- skew(save);
- split(save);
- inserted
- }
- Equal => {
- save.key = key;
- Some(replace(&mut save.value, value))
- }
- }
- }
- None => {
- *node = Some(box TreeNode::new(key, value));
- None
- }
- }
-}
-
-fn remove<K: Ord, V>(node: &mut Option<Box<TreeNode<K, V>>>,
- key: &K) -> Option<V> {
- fn heir_swap<K: Ord, V>(node: &mut Box<TreeNode<K, V>>,
- child: &mut Option<Box<TreeNode<K, V>>>) {
- // *could* be done without recursion, but it won't borrow check
- for x in child.iter_mut() {
- if x.right.is_some() {
- heir_swap(node, &mut x.right);
- } else {
- swap(&mut node.key, &mut x.key);
- swap(&mut node.value, &mut x.value);
- }
- }
- }
-
- match *node {
- None => {
- return None; // bottom of tree
- }
- Some(ref mut save) => {
- let (ret, rebalance) = match key.cmp(&save.key) {
- Less => (remove(&mut save.left, key), true),
- Greater => (remove(&mut save.right, key), true),
- Equal => {
- if save.left.is_some() {
- if save.right.is_some() {
- let mut left = save.left.take().unwrap();
- if left.right.is_some() {
- heir_swap(save, &mut left.right);
- } else {
- swap(&mut save.key, &mut left.key);
- swap(&mut save.value, &mut left.value);
- }
- save.left = Some(left);
- (remove(&mut save.left, key), true)
- } else {
- let new = save.left.take().unwrap();
- let box TreeNode{value, ..} = replace(save, new);
- *save = save.left.take().unwrap();
- (Some(value), true)
- }
- } else if save.right.is_some() {
- let new = save.right.take().unwrap();
- let box TreeNode{value, ..} = replace(save, new);
- (Some(value), true)
- } else {
- (None, false)
- }
- }
- };
-
- if rebalance {
- let left_level = save.left.as_ref().map_or(0, |x| x.level);
- let right_level = save.right.as_ref().map_or(0, |x| x.level);
-
- // re-balance, if necessary
- if left_level < save.level - 1 || right_level < save.level - 1 {
- save.level -= 1;
-
- if right_level > save.level {
- let save_level = save.level;
- for x in save.right.iter_mut() { x.level = save_level }
- }
-
- skew(save);
-
- for right in save.right.iter_mut() {
- skew(right);
- for x in right.right.iter_mut() { skew(x) }
- }
-
- split(save);
- for x in save.right.iter_mut() { split(x) }
- }
-
- return ret;
- }
- }
- }
- return match node.take() {
- Some(box TreeNode{value, ..}) => Some(value), None => panic!()
- };
-}
-
-impl<K: Ord, V> FromIterator<(K, V)> for TreeMap<K, V> {
- fn from_iter<T: Iterator<(K, V)>>(iter: T) -> TreeMap<K, V> {
- let mut map = TreeMap::new();
- map.extend(iter);
- map
- }
-}
-
-impl<K: Ord, V> Extendable<(K, V)> for TreeMap<K, V> {
- #[inline]
- fn extend<T: Iterator<(K, V)>>(&mut self, mut iter: T) {
- for (k, v) in iter {
- self.insert(k, v);
- }
- }
-}
-
-impl<S: Writer, K: Ord + Hash<S>, V: Hash<S>> Hash<S> for TreeMap<K, V> {
- fn hash(&self, state: &mut S) {
- for elt in self.iter() {
- elt.hash(state);
- }
- }
-}
-
-impl<T: Ord> FromIterator<T> for TreeSet<T> {
- fn from_iter<Iter: Iterator<T>>(iter: Iter) -> TreeSet<T> {
- let mut set = TreeSet::new();
- set.extend(iter);
- set
- }
-}
-
-impl<T: Ord> Extendable<T> for TreeSet<T> {
- #[inline]
- fn extend<Iter: Iterator<T>>(&mut self, mut iter: Iter) {
- for elem in iter {
- self.insert(elem);
- }
- }
-}
-
-impl<S: Writer, T: Ord + Hash<S>> Hash<S> for TreeSet<T> {
- fn hash(&self, state: &mut S) {
- for elt in self.iter() {
- elt.hash(state);
- }
- }
-}
-
-#[cfg(test)]
-mod test_treemap {
- use std::prelude::*;
- use std::rand::Rng;
- use std::rand;
-
- use super::{TreeMap, TreeNode};
-
- #[test]
- fn find_empty() {
- let m: TreeMap<int,int> = TreeMap::new();
- assert!(m.find(&5) == None);
- }
-
- #[test]
- fn find_not_found() {
- let mut m = TreeMap::new();
- assert!(m.insert(1i, 2i));
- assert!(m.insert(5i, 3i));
- assert!(m.insert(9i, 3i));
- assert_eq!(m.find(&2), None);
- }
-
- #[test]
- fn find_with_empty() {
- let m: TreeMap<&'static str,int> = TreeMap::new();
- assert!(m.find_with(|k| "test".cmp(k)) == None);
- }
-
- #[test]
- fn find_with_not_found() {
- let mut m = TreeMap::new();
- assert!(m.insert("test1", 2i));
- assert!(m.insert("test2", 3i));
- assert!(m.insert("test3", 3i));
- assert_eq!(m.find_with(|k| "test4".cmp(k)), None);
- }
-
- #[test]
- fn find_with_found() {
- let mut m = TreeMap::new();
- assert!(m.insert("test1", 2i));
- assert!(m.insert("test2", 3i));
- assert!(m.insert("test3", 4i));
- assert_eq!(m.find_with(|k| "test2".cmp(k)), Some(&3i));
- }
-
- #[test]
- fn test_find_mut() {
- let mut m = TreeMap::new();
- assert!(m.insert(1i, 12i));
- assert!(m.insert(2, 8));
- assert!(m.insert(5, 14));
- let new = 100;
- match m.find_mut(&5) {
- None => panic!(), Some(x) => *x = new
- }
- assert_eq!(m.find(&5), Some(&new));
- }
-
- #[test]
- fn test_find_with_mut() {
- let mut m = TreeMap::new();
- assert!(m.insert("t1", 12i));
- assert!(m.insert("t2", 8));
- assert!(m.insert("t5", 14));
- let new = 100;
- match m.find_with_mut(|k| "t5".cmp(k)) {
- None => panic!(), Some(x) => *x = new
- }
- assert_eq!(m.find_with(|k| "t5".cmp(k)), Some(&new));
- }
-
- #[test]
- fn insert_replace() {
- let mut m = TreeMap::new();
- assert!(m.insert(5i, 2i));
- assert!(m.insert(2, 9));
- assert!(!m.insert(2, 11));
- assert_eq!(m.find(&2).unwrap(), &11);
- }
-
- #[test]
- fn test_clear() {
- let mut m = TreeMap::new();
- m.clear();
- assert!(m.insert(5i, 11i));
- assert!(m.insert(12, -3));
- assert!(m.insert(19, 2));
- m.clear();
- assert!(m.find(&5).is_none());
- assert!(m.find(&12).is_none());
- assert!(m.find(&19).is_none());
- assert!(m.is_empty());
- }
-
- #[test]
- fn u8_map() {
- let mut m = TreeMap::new();
-
- let k1 = "foo".as_bytes();
- let k2 = "bar".as_bytes();
- let v1 = "baz".as_bytes();
- let v2 = "foobar".as_bytes();
-
- m.insert(k1.clone(), v1.clone());
- m.insert(k2.clone(), v2.clone());
-
- assert_eq!(m.find(&k2), Some(&v2));
- assert_eq!(m.find(&k1), Some(&v1));
- }
-
- fn check_equal<K: PartialEq + Ord, V: PartialEq>(ctrl: &[(K, V)],
- map: &TreeMap<K, V>) {
- assert_eq!(ctrl.is_empty(), map.is_empty());
- for x in ctrl.iter() {
- let &(ref k, ref v) = x;
- assert!(map.find(k).unwrap() == v)
- }
- for (map_k, map_v) in map.iter() {
- let mut found = false;
- for x in ctrl.iter() {
- let &(ref ctrl_k, ref ctrl_v) = x;
- if *map_k == *ctrl_k {
- assert!(*map_v == *ctrl_v);
- found = true;
- break;
- }
- }
- assert!(found);
- }
- }
-
- fn check_left<K: Ord, V>(node: &Option<Box<TreeNode<K, V>>>,
- parent: &Box<TreeNode<K, V>>) {
- match *node {
- Some(ref r) => {
- assert_eq!(r.key.cmp(&parent.key), Less);
- assert!(r.level == parent.level - 1); // left is black
- check_left(&r.left, r);
- check_right(&r.right, r, false);
- }
- None => assert!(parent.level == 1) // parent is leaf
- }
- }
-
- fn check_right<K: Ord, V>(node: &Option<Box<TreeNode<K, V>>>,
- parent: &Box<TreeNode<K, V>>,
- parent_red: bool) {
- match *node {
- Some(ref r) => {
- assert_eq!(r.key.cmp(&parent.key), Greater);
- let red = r.level == parent.level;
- if parent_red { assert!(!red) } // no dual horizontal links
- // Right red or black
- assert!(red || r.level == parent.level - 1);
- check_left(&r.left, r);
- check_right(&r.right, r, red);
- }
- None => assert!(parent.level == 1) // parent is leaf
- }
- }
-
- fn check_structure<K: Ord, V>(map: &TreeMap<K, V>) {
- match map.root {
- Some(ref r) => {
- check_left(&r.left, r);
- check_right(&r.right, r, false);
- }
- None => ()
- }
- }
-
- #[test]
- fn test_rand_int() {
- let mut map: TreeMap<int,int> = TreeMap::new();
- let mut ctrl = vec![];
-
- check_equal(ctrl.as_slice(), &map);
- assert!(map.find(&5).is_none());
-
- let seed: &[_] = &[42];
- let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed);
-
- for _ in range(0u, 3) {
- for _ in range(0u, 90) {
- let k = rng.gen();
- let v = rng.gen();
- if !ctrl.iter().any(|x| x == &(k, v)) {
- assert!(map.insert(k, v));
- ctrl.push((k, v));
- check_structure(&map);
- check_equal(ctrl.as_slice(), &map);
- }
- }
-
- for _ in range(0u, 30) {
- let r = rng.gen_range(0, ctrl.len());
- let (key, _) = ctrl.remove(r).unwrap();
- assert!(map.remove(&key));
- check_structure(&map);
- check_equal(ctrl.as_slice(), &map);
- }
- }
- }
-
- #[test]
- fn test_len() {
- let mut m = TreeMap::new();
- assert!(m.insert(3i, 6i));
- assert_eq!(m.len(), 1);
- assert!(m.insert(0, 0));
- assert_eq!(m.len(), 2);
- assert!(m.insert(4, 8));
- assert_eq!(m.len(), 3);
- assert!(m.remove(&3));
- assert_eq!(m.len(), 2);
- assert!(!m.remove(&5));
- assert_eq!(m.len(), 2);
- assert!(m.insert(2, 4));
- assert_eq!(m.len(), 3);
- assert!(m.insert(1, 2));
- assert_eq!(m.len(), 4);
- }
-
- #[test]
- fn test_iterator() {
- let mut m = TreeMap::new();
-
- assert!(m.insert(3i, 6i));
- assert!(m.insert(0, 0));
- assert!(m.insert(4, 8));
- assert!(m.insert(2, 4));
- assert!(m.insert(1, 2));
-
- let mut n = 0;
- for (k, v) in m.iter() {
- assert_eq!(*k, n);
- assert_eq!(*v, n * 2);
- n += 1;
- }
- assert_eq!(n, 5);
- }
-
- #[test]
- fn test_interval_iteration() {
- let mut m = TreeMap::new();
- for i in range(1i, 100i) {
- assert!(m.insert(i * 2, i * 4));
- }
-
- for i in range(1i, 198i) {
- let mut lb_it = m.lower_bound(&i);
- let (&k, &v) = lb_it.next().unwrap();
- let lb = i + i % 2;
- assert_eq!(lb, k);
- assert_eq!(lb * 2, v);
-
- let mut ub_it = m.upper_bound(&i);
- let (&k, &v) = ub_it.next().unwrap();
- let ub = i + 2 - i % 2;
- assert_eq!(ub, k);
- assert_eq!(ub * 2, v);
- }
- let mut end_it = m.lower_bound(&199);
- assert_eq!(end_it.next(), None);
- }
-
- #[test]
- fn test_rev_iter() {
- let mut m = TreeMap::new();
-
- assert!(m.insert(3i, 6i));
- assert!(m.insert(0, 0));
- assert!(m.insert(4, 8));
- assert!(m.insert(2, 4));
- assert!(m.insert(1, 2));
-
- let mut n = 4;
- for (k, v) in m.rev_iter() {
- assert_eq!(*k, n);
- assert_eq!(*v, n * 2);
- n -= 1;
- }
- }
-
- #[test]
- fn test_mut_iter() {
- let mut m = TreeMap::new();
- for i in range(0u, 10) {
- assert!(m.insert(i, 100 * i));
- }
-
- for (i, (&k, v)) in m.iter_mut().enumerate() {
- *v += k * 10 + i; // 000 + 00 + 0, 100 + 10 + 1, ...
- }
-
- for (&k, &v) in m.iter() {
- assert_eq!(v, 111 * k);
- }
- }
- #[test]
- fn test_mut_rev_iter() {
- let mut m = TreeMap::new();
- for i in range(0u, 10) {
- assert!(m.insert(i, 100 * i));
- }
-
- for (i, (&k, v)) in m.rev_iter_mut().enumerate() {
- *v += k * 10 + (9 - i); // 900 + 90 + (9 - 0), 800 + 80 + (9 - 1), ...
- }
-
- for (&k, &v) in m.iter() {
- assert_eq!(v, 111 * k);
- }
- }
-
- #[test]
- fn test_mut_interval_iter() {
- let mut m_lower = TreeMap::new();
- let mut m_upper = TreeMap::new();
- for i in range(1i, 100i) {
- assert!(m_lower.insert(i * 2, i * 4));
- assert!(m_upper.insert(i * 2, i * 4));
- }
-
- for i in range(1i, 199) {
- let mut lb_it = m_lower.lower_bound_mut(&i);
- let (&k, v) = lb_it.next().unwrap();
- let lb = i + i % 2;
- assert_eq!(lb, k);
- *v -= k;
- }
- for i in range(0i, 198) {
- let mut ub_it = m_upper.upper_bound_mut(&i);
- let (&k, v) = ub_it.next().unwrap();
- let ub = i + 2 - i % 2;
- assert_eq!(ub, k);
- *v -= k;
- }
-
- assert!(m_lower.lower_bound_mut(&199).next().is_none());
-
- assert!(m_upper.upper_bound_mut(&198).next().is_none());
-
- assert!(m_lower.iter().all(|(_, &x)| x == 0));
- assert!(m_upper.iter().all(|(_, &x)| x == 0));
- }
-
- #[test]
- fn test_keys() {
- let vec = vec![(1i, 'a'), (2i, 'b'), (3i, 'c')];
- let map = vec.into_iter().collect::<TreeMap<int, char>>();
- let keys = map.keys().map(|&k| k).collect::<Vec<int>>();
- assert_eq!(keys.len(), 3);
- assert!(keys.contains(&1));
- assert!(keys.contains(&2));
- assert!(keys.contains(&3));
- }
-
- #[test]
- fn test_values() {
- let vec = vec![(1i, 'a'), (2i, 'b'), (3i, 'c')];
- let map = vec.into_iter().collect::<TreeMap<int, char>>();
- let values = map.values().map(|&v| v).collect::<Vec<char>>();
- assert_eq!(values.len(), 3);
- assert!(values.contains(&'a'));
- assert!(values.contains(&'b'));
- assert!(values.contains(&'c'));
- }
-
- #[test]
- fn test_eq() {
- let mut a = TreeMap::new();
- let mut b = TreeMap::new();
-
- assert!(a == b);
- assert!(a.insert(0i, 5i));
- assert!(a != b);
- assert!(b.insert(0, 4));
- assert!(a != b);
- assert!(a.insert(5, 19));
- assert!(a != b);
- assert!(!b.insert(0, 5));
- assert!(a != b);
- assert!(b.insert(5, 19));
- assert!(a == b);
- }
-
- #[test]
- fn test_lt() {
- let mut a = TreeMap::new();
- let mut b = TreeMap::new();
-
- assert!(!(a < b) && !(b < a));
- assert!(b.insert(0i, 5i));
- assert!(a < b);
- assert!(a.insert(0, 7));
- assert!(!(a < b) && b < a);
- assert!(b.insert(-2, 0));
- assert!(b < a);
- assert!(a.insert(-5, 2));
- assert!(a < b);
- assert!(a.insert(6, 2));
- assert!(a < b && !(b < a));
- }
-
- #[test]
- fn test_ord() {
- let mut a = TreeMap::new();
- let mut b = TreeMap::new();
-
- assert!(a <= b && a >= b);
- assert!(a.insert(1i, 1i));
- assert!(a > b && a >= b);
- assert!(b < a && b <= a);
- assert!(b.insert(2, 2));
- assert!(b > a && b >= a);
- assert!(a < b && a <= b);
- }
-
- #[test]
- fn test_show() {
- let mut map: TreeMap<int, int> = TreeMap::new();
- let empty: TreeMap<int, int> = TreeMap::new();
-
- map.insert(1, 2);
- map.insert(3, 4);
-
- let map_str = format!("{}", map);
-
- assert!(map_str == "{1: 2, 3: 4}".to_string());
- assert_eq!(format!("{}", empty), "{}".to_string());
- }
-
- #[test]
- fn test_lazy_iterator() {
- let mut m = TreeMap::new();
- let (x1, y1) = (2i, 5i);
- let (x2, y2) = (9, 12);
- let (x3, y3) = (20, -3);
- let (x4, y4) = (29, 5);
- let (x5, y5) = (103, 3);
-
- assert!(m.insert(x1, y1));
- assert!(m.insert(x2, y2));
- assert!(m.insert(x3, y3));
- assert!(m.insert(x4, y4));
- assert!(m.insert(x5, y5));
-
- let m = m;
- let mut a = m.iter();
-
- assert_eq!(a.next().unwrap(), (&x1, &y1));
- assert_eq!(a.next().unwrap(), (&x2, &y2));
- assert_eq!(a.next().unwrap(), (&x3, &y3));
- assert_eq!(a.next().unwrap(), (&x4, &y4));
- assert_eq!(a.next().unwrap(), (&x5, &y5));
-
- assert!(a.next().is_none());
-
- let mut b = m.iter();
-
- let expected = [(&x1, &y1), (&x2, &y2), (&x3, &y3), (&x4, &y4),
- (&x5, &y5)];
- let mut i = 0;
-
- for x in b {
- assert_eq!(expected[i], x);
- i += 1;
-
- if i == 2 {
- break
- }
- }
-
- for x in b {
- assert_eq!(expected[i], x);
- i += 1;
- }
- }
-
- #[test]
- fn test_from_iter() {
- let xs = [(1i, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
- let map: TreeMap<int, int> = xs.iter().map(|&x| x).collect();
-
- for &(k, v) in xs.iter() {
- assert_eq!(map.find(&k), Some(&v));
- }
- }
-
- #[test]
- fn test_index() {
- let mut map: TreeMap<int, int> = TreeMap::new();
-
- map.insert(1, 2);
- map.insert(2, 1);
- map.insert(3, 4);
-
- assert_eq!(map[2], 1);
- }
-
- #[test]
- #[should_fail]
- fn test_index_nonexistent() {
- let mut map: TreeMap<int, int> = TreeMap::new();
-
- map.insert(1, 2);
- map.insert(2, 1);
- map.insert(3, 4);
-
- map[4];
- }
-}
-
-#[cfg(test)]
-mod bench {
- use std::prelude::*;
- use std::rand::{weak_rng, Rng};
- use test::{Bencher, black_box};
-
- use super::TreeMap;
- use bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n};
-
- #[bench]
- pub fn insert_rand_100(b: &mut Bencher) {
- let mut m : TreeMap<uint,uint> = TreeMap::new();
- insert_rand_n(100, &mut m, b,
- |m, i| { m.insert(i, 1); },
- |m, i| { m.remove(&i); });
- }
-
- #[bench]
- pub fn insert_rand_10_000(b: &mut Bencher) {
- let mut m : TreeMap<uint,uint> = TreeMap::new();
- insert_rand_n(10_000, &mut m, b,
- |m, i| { m.insert(i, 1); },
- |m, i| { m.remove(&i); });
- }
-
- // Insert seq
- #[bench]
- pub fn insert_seq_100(b: &mut Bencher) {
- let mut m : TreeMap<uint,uint> = TreeMap::new();
- insert_seq_n(100, &mut m, b,
- |m, i| { m.insert(i, 1); },
- |m, i| { m.remove(&i); });
- }
-
- #[bench]
- pub fn insert_seq_10_000(b: &mut Bencher) {
- let mut m : TreeMap<uint,uint> = TreeMap::new();
- insert_seq_n(10_000, &mut m, b,
- |m, i| { m.insert(i, 1); },
- |m, i| { m.remove(&i); });
- }
-
- // Find rand
- #[bench]
- pub fn find_rand_100(b: &mut Bencher) {
- let mut m : TreeMap<uint,uint> = TreeMap::new();
- find_rand_n(100, &mut m, b,
- |m, i| { m.insert(i, 1); },
- |m, i| { m.find(&i); });
- }
-
- #[bench]
- pub fn find_rand_10_000(b: &mut Bencher) {
- let mut m : TreeMap<uint,uint> = TreeMap::new();
- find_rand_n(10_000, &mut m, b,
- |m, i| { m.insert(i, 1); },
- |m, i| { m.find(&i); });
- }
-
- // Find seq
- #[bench]
- pub fn find_seq_100(b: &mut Bencher) {
- let mut m : TreeMap<uint,uint> = TreeMap::new();
- find_seq_n(100, &mut m, b,
- |m, i| { m.insert(i, 1); },
- |m, i| { m.find(&i); });
- }
-
- #[bench]
- pub fn find_seq_10_000(b: &mut Bencher) {
- let mut m : TreeMap<uint,uint> = TreeMap::new();
- find_seq_n(10_000, &mut m, b,
- |m, i| { m.insert(i, 1); },
- |m, i| { m.find(&i); });
- }
-
- fn bench_iter(b: &mut Bencher, size: uint) {
- let mut map = TreeMap::<uint, uint>::new();
- let mut rng = weak_rng();
-
- for _ in range(0, size) {
- map.swap(rng.gen(), rng.gen());
- }
-
- b.iter(|| {
- for entry in map.iter() {
- black_box(entry);
- }
- });
- }
-
- #[bench]
- pub fn iter_20(b: &mut Bencher) {
- bench_iter(b, 20);
- }
-
- #[bench]
- pub fn iter_1000(b: &mut Bencher) {
- bench_iter(b, 1000);
- }
-
- #[bench]
- pub fn iter_100000(b: &mut Bencher) {
- bench_iter(b, 100000);
- }
-}
-
-#[cfg(test)]
-mod test_set {
- use std::prelude::*;
- use std::hash;
-
- use super::{TreeMap, TreeSet};
-
- #[test]
- fn test_clear() {
- let mut s = TreeSet::new();
- s.clear();
- assert!(s.insert(5i));
- assert!(s.insert(12));
- assert!(s.insert(19));
- s.clear();
- assert!(!s.contains(&5));
- assert!(!s.contains(&12));
- assert!(!s.contains(&19));
- assert!(s.is_empty());
- }
-
- #[test]
- fn test_disjoint() {
- let mut xs = TreeSet::new();
- let mut ys = TreeSet::new();
- assert!(xs.is_disjoint(&ys));
- assert!(ys.is_disjoint(&xs));
- assert!(xs.insert(5i));
- assert!(ys.insert(11i));
- assert!(xs.is_disjoint(&ys));
- assert!(ys.is_disjoint(&xs));
- assert!(xs.insert(7));
- assert!(xs.insert(19));
- assert!(xs.insert(4));
- assert!(ys.insert(2));
- assert!(ys.insert(-11));
- assert!(xs.is_disjoint(&ys));
- assert!(ys.is_disjoint(&xs));
- assert!(ys.insert(7));
- assert!(!xs.is_disjoint(&ys));
- assert!(!ys.is_disjoint(&xs));
- }
-
- #[test]
- fn test_subset_and_superset() {
- let mut a = TreeSet::new();
- assert!(a.insert(0i));
- assert!(a.insert(5));
- assert!(a.insert(11));
- assert!(a.insert(7));
-
- let mut b = TreeSet::new();
- assert!(b.insert(0i));
- assert!(b.insert(7));
- assert!(b.insert(19));
- assert!(b.insert(250));
- assert!(b.insert(11));
- assert!(b.insert(200));
-
- assert!(!a.is_subset(&b));
- assert!(!a.is_superset(&b));
- assert!(!b.is_subset(&a));
- assert!(!b.is_superset(&a));
-
- assert!(b.insert(5));
-
- assert!(a.is_subset(&b));
- assert!(!a.is_superset(&b));
- assert!(!b.is_subset(&a));
- assert!(b.is_superset(&a));
- }
-
- #[test]
- fn test_iterator() {
- let mut m = TreeSet::new();
-
- assert!(m.insert(3i));
- assert!(m.insert(0));
- assert!(m.insert(4));
- assert!(m.insert(2));
- assert!(m.insert(1));
-
- let mut n = 0;
- for x in m.iter() {
- assert_eq!(*x, n);
- n += 1
- }
- }
-
- #[test]
- fn test_rev_iter() {
- let mut m = TreeSet::new();
-
- assert!(m.insert(3i));
- assert!(m.insert(0));
- assert!(m.insert(4));
- assert!(m.insert(2));
- assert!(m.insert(1));
-
- let mut n = 4;
- for x in m.rev_iter() {
- assert_eq!(*x, n);
- n -= 1;
- }
- }
-
- #[test]
- fn test_move_iter() {
- let s: TreeSet<int> = range(0i, 5).collect();
-
- let mut n = 0;
- for x in s.into_iter() {
- assert_eq!(x, n);
- n += 1;
- }
- }
-
- #[test]
- fn test_move_iter_size_hint() {
- let s: TreeSet<int> = vec!(0i, 1).into_iter().collect();
-
- let mut it = s.into_iter();
-
- assert_eq!(it.size_hint(), (2, Some(2)));
- assert!(it.next() != None);
-
- assert_eq!(it.size_hint(), (1, Some(1)));
- assert!(it.next() != None);
-
- assert_eq!(it.size_hint(), (0, Some(0)));
- assert_eq!(it.next(), None);
- }
-
- #[test]
- fn test_clone_eq() {
- let mut m = TreeSet::new();
-
- m.insert(1i);
- m.insert(2);
-
- assert!(m.clone() == m);
- }
-
- #[test]
- fn test_hash() {
- let mut x = TreeSet::new();
- let mut y = TreeSet::new();
-
- x.insert(1i);
- x.insert(2);
- x.insert(3);
-
- y.insert(3i);
- y.insert(2);
- y.insert(1);
-
- assert!(hash::hash(&x) == hash::hash(&y));
- }
-
- fn check(a: &[int],
- b: &[int],
- expected: &[int],
- f: |&TreeSet<int>, &TreeSet<int>, f: |&int| -> bool| -> bool) {
- let mut set_a = TreeSet::new();
- let mut set_b = TreeSet::new();
-
- for x in a.iter() { assert!(set_a.insert(*x)) }
- for y in b.iter() { assert!(set_b.insert(*y)) }
-
- let mut i = 0;
- f(&set_a, &set_b, |x| {
- assert_eq!(*x, expected[i]);
- i += 1;
- true
- });
- assert_eq!(i, expected.len());
- }
-
- #[test]
- fn test_intersection() {
- fn check_intersection(a: &[int], b: &[int], expected: &[int]) {
- check(a, b, expected, |x, y, f| x.intersection(y).all(f))
- }
-
- check_intersection([], [], []);
- check_intersection([1, 2, 3], [], []);
- check_intersection([], [1, 2, 3], []);
- check_intersection([2], [1, 2, 3], [2]);
- check_intersection([1, 2, 3], [2], [2]);
- check_intersection([11, 1, 3, 77, 103, 5, -5],
- [2, 11, 77, -9, -42, 5, 3],
- [3, 5, 11, 77]);
- }
-
- #[test]
- fn test_difference() {
- fn check_difference(a: &[int], b: &[int], expected: &[int]) {
- check(a, b, expected, |x, y, f| x.difference(y).all(f))
- }
-
- check_difference([], [], []);
- check_difference([1, 12], [], [1, 12]);
- check_difference([], [1, 2, 3, 9], []);
- check_difference([1, 3, 5, 9, 11],
- [3, 9],
- [1, 5, 11]);
- check_difference([-5, 11, 22, 33, 40, 42],
- [-12, -5, 14, 23, 34, 38, 39, 50],
- [11, 22, 33, 40, 42]);
- }
-
- #[test]
- fn test_symmetric_difference() {
- fn check_symmetric_difference(a: &[int], b: &[int],
- expected: &[int]) {
- check(a, b, expected, |x, y, f| x.symmetric_difference(y).all(f))
- }
-
- check_symmetric_difference([], [], []);
- check_symmetric_difference([1, 2, 3], [2], [1, 3]);
- check_symmetric_difference([2], [1, 2, 3], [1, 3]);
- check_symmetric_difference([1, 3, 5, 9, 11],
- [-2, 3, 9, 14, 22],
- [-2, 1, 5, 11, 14, 22]);
- }
-
- #[test]
- fn test_union() {
- fn check_union(a: &[int], b: &[int],
- expected: &[int]) {
- check(a, b, expected, |x, y, f| x.union(y).all(f))
- }
-
- check_union([], [], []);
- check_union([1, 2, 3], [2], [1, 2, 3]);
- check_union([2], [1, 2, 3], [1, 2, 3]);
- check_union([1, 3, 5, 9, 11, 16, 19, 24],
- [-2, 1, 5, 9, 13, 19],
- [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]);
- }
-
- #[test]
- fn test_zip() {
- let mut x = TreeSet::new();
- x.insert(5u);
- x.insert(12u);
- x.insert(11u);
-
- let mut y = TreeSet::new();
- y.insert("foo");
- y.insert("bar");
-
- let x = x;
- let y = y;
- let mut z = x.iter().zip(y.iter());
-
- // FIXME: #5801: this needs a type hint to compile...
- let result: Option<(&uint, & &'static str)> = z.next();
- assert_eq!(result.unwrap(), (&5u, &("bar")));
-
- let result: Option<(&uint, & &'static str)> = z.next();
- assert_eq!(result.unwrap(), (&11u, &("foo")));
-
- let result: Option<(&uint, & &'static str)> = z.next();
- assert!(result.is_none());
- }
-
- #[test]
- fn test_swap() {
- let mut m = TreeMap::new();
- assert_eq!(m.swap(1u, 2i), None);
- assert_eq!(m.swap(1u, 3i), Some(2));
- assert_eq!(m.swap(1u, 4i), Some(3));
- }
-
- #[test]
- fn test_pop() {
- let mut m = TreeMap::new();
- m.insert(1u, 2i);
- assert_eq!(m.pop(&1), Some(2));
- assert_eq!(m.pop(&1), None);
- }
-
- #[test]
- fn test_from_iter() {
- let xs = [1i, 2, 3, 4, 5, 6, 7, 8, 9];
-
- let set: TreeSet<int> = xs.iter().map(|&x| x).collect();
-
- for x in xs.iter() {
- assert!(set.contains(x));
- }
- }
-
- #[test]
- fn test_show() {
- let mut set: TreeSet<int> = TreeSet::new();
- let empty: TreeSet<int> = TreeSet::new();
-
- set.insert(1);
- set.insert(2);
-
- let set_str = format!("{}", set);
-
- assert!(set_str == "{1, 2}".to_string());
- assert_eq!(format!("{}", empty), "{}".to_string());
- }
-}
+++ /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.
-
-//! Maps are collections of unique keys with corresponding values, and sets are
-//! just unique keys without a corresponding value. The `Map` and `Set` traits in
-//! `std::container` define the basic interface.
-//!
-//! This crate defines `TrieMap` and `TrieSet`, which require `uint` keys.
-//!
-//! `TrieMap` is ordered.
-
-use core::prelude::*;
-
-use alloc::boxed::Box;
-use core::default::Default;
-use core::fmt;
-use core::fmt::Show;
-use core::mem::zeroed;
-use core::mem;
-use core::ops::{Slice,SliceMut};
-use core::uint;
-use core::iter;
-use std::hash::{Writer, Hash};
-
-use slice::{Items, MutItems};
-use slice;
-
-// FIXME: #5244: need to manually update the TrieNode constructor
-const SHIFT: uint = 4;
-const SIZE: uint = 1 << SHIFT;
-const MASK: uint = SIZE - 1;
-const NUM_CHUNKS: uint = uint::BITS / SHIFT;
-
-#[deriving(Clone)]
-enum Child<T> {
- Internal(Box<TrieNode<T>>),
- External(uint, T),
- Nothing
-}
-
-/// A map implemented as a radix trie.
-///
-/// # Example
-///
-/// ```
-/// use std::collections::TrieMap;
-///
-/// let mut map = TrieMap::new();
-/// map.insert(27, "Olaf");
-/// map.insert(1, "Edgar");
-/// map.insert(13, "Ruth");
-/// map.insert(1, "Martin");
-///
-/// assert_eq!(map.len(), 3);
-/// assert_eq!(map.find(&1), Some(&"Martin"));
-///
-/// if !map.contains_key(&90) {
-/// println!("Nobody is keyed 90");
-/// }
-///
-/// // Update a key
-/// match map.find_mut(&1) {
-/// Some(value) => *value = "Olga",
-/// None => (),
-/// }
-///
-/// map.remove(&13);
-/// assert_eq!(map.len(), 2);
-///
-/// // Print the key value pairs, ordered by key.
-/// for (key, value) in map.iter() {
-/// // Prints `1: Olga` then `27: Olaf`
-/// println!("{}: {}", key, value);
-/// }
-///
-/// map.clear();
-/// assert!(map.is_empty());
-/// ```
-#[deriving(Clone)]
-pub struct TrieMap<T> {
- root: TrieNode<T>,
- length: uint
-}
-
-impl<T: PartialEq> PartialEq for TrieMap<T> {
- fn eq(&self, other: &TrieMap<T>) -> bool {
- self.len() == other.len() &&
- self.iter().zip(other.iter()).all(|(a, b)| a == b)
- }
-}
-
-impl<T: Eq> Eq for TrieMap<T> {}
-
-impl<T: PartialOrd> PartialOrd for TrieMap<T> {
- #[inline]
- fn partial_cmp(&self, other: &TrieMap<T>) -> Option<Ordering> {
- iter::order::partial_cmp(self.iter(), other.iter())
- }
-}
-
-impl<T: Ord> Ord for TrieMap<T> {
- #[inline]
- fn cmp(&self, other: &TrieMap<T>) -> Ordering {
- iter::order::cmp(self.iter(), other.iter())
- }
-}
-
-impl<T: Show> Show for TrieMap<T> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- try!(write!(f, "{{"));
-
- for (i, (k, v)) in self.iter().enumerate() {
- if i != 0 { try!(write!(f, ", ")); }
- try!(write!(f, "{}: {}", k, *v));
- }
-
- write!(f, "}}")
- }
-}
-
-impl<T> Default for TrieMap<T> {
- #[inline]
- fn default() -> TrieMap<T> { TrieMap::new() }
-}
-
-impl<T> TrieMap<T> {
- /// Creates an empty `TrieMap`.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieMap;
- /// let mut map: TrieMap<&str> = TrieMap::new();
- /// ```
- #[inline]
- pub fn new() -> TrieMap<T> {
- TrieMap{root: TrieNode::new(), length: 0}
- }
-
- /// Visits all key-value pairs in reverse order. Aborts traversal when `f` returns `false`.
- /// Returns `true` if `f` returns `true` for all elements.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieMap;
- /// let map: TrieMap<&str> = [(1, "a"), (2, "b"), (3, "c")].iter().map(|&x| x).collect();
- ///
- /// let mut vec = Vec::new();
- /// assert_eq!(true, map.each_reverse(|&key, &value| { vec.push((key, value)); true }));
- /// assert_eq!(vec, vec![(3, "c"), (2, "b"), (1, "a")]);
- ///
- /// // Stop when we reach 2
- /// let mut vec = Vec::new();
- /// assert_eq!(false, map.each_reverse(|&key, &value| { vec.push(value); key != 2 }));
- /// assert_eq!(vec, vec!["c", "b"]);
- /// ```
- #[inline]
- pub fn each_reverse<'a>(&'a self, f: |&uint, &'a T| -> bool) -> bool {
- self.root.each_reverse(f)
- }
-
- /// Gets an iterator visiting all keys in ascending order by the keys.
- /// The iterator's element type is `uint`.
- pub fn keys<'r>(&'r self) -> Keys<'r, T> {
- self.iter().map(|(k, _v)| k)
- }
-
- /// Gets an iterator visiting all values in ascending order by the keys.
- /// The iterator's element type is `&'r T`.
- pub fn values<'r>(&'r self) -> Values<'r, T> {
- self.iter().map(|(_k, v)| v)
- }
-
- /// Gets an iterator over the key-value pairs in the map, ordered by keys.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieMap;
- /// let map: TrieMap<&str> = [(3, "c"), (1, "a"), (2, "b")].iter().map(|&x| x).collect();
- ///
- /// for (key, value) in map.iter() {
- /// println!("{}: {}", key, value);
- /// }
- /// ```
- pub fn iter<'a>(&'a self) -> Entries<'a, T> {
- let mut iter = unsafe {Entries::new()};
- iter.stack[0] = self.root.children.iter();
- iter.length = 1;
- iter.remaining_min = self.length;
- iter.remaining_max = self.length;
-
- iter
- }
-
- /// Gets an iterator over the key-value pairs in the map, with the
- /// ability to mutate the values.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieMap;
- /// let mut map: TrieMap<int> = [(1, 2), (2, 4), (3, 6)].iter().map(|&x| x).collect();
- ///
- /// for (key, value) in map.iter_mut() {
- /// *value = -(key as int);
- /// }
- ///
- /// assert_eq!(map.find(&1), Some(&-1));
- /// assert_eq!(map.find(&2), Some(&-2));
- /// assert_eq!(map.find(&3), Some(&-3));
- /// ```
- pub fn iter_mut<'a>(&'a mut self) -> MutEntries<'a, T> {
- let mut iter = unsafe {MutEntries::new()};
- iter.stack[0] = self.root.children.iter_mut();
- iter.length = 1;
- iter.remaining_min = self.length;
- iter.remaining_max = self.length;
-
- iter
- }
-
- /// Return the number of elements in the map.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieMap;
- ///
- /// let mut a = TrieMap::new();
- /// assert_eq!(a.len(), 0);
- /// a.insert(1, "a");
- /// assert_eq!(a.len(), 1);
- /// ```
- #[inline]
- pub fn len(&self) -> uint { self.length }
-
- /// Return true if the map contains no elements.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieMap;
- ///
- /// let mut a = TrieMap::new();
- /// assert!(a.is_empty());
- /// a.insert(1, "a");
- /// assert!(!a.is_empty());
- /// ```
- #[inline]
- pub fn is_empty(&self) -> bool { self.len() == 0 }
-
- /// Clears the map, removing all values.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieMap;
- ///
- /// let mut a = TrieMap::new();
- /// a.insert(1, "a");
- /// a.clear();
- /// assert!(a.is_empty());
- /// ```
- #[inline]
- pub fn clear(&mut self) {
- self.root = TrieNode::new();
- self.length = 0;
- }
-
- /// Returns a reference to the value corresponding to the key.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieMap;
- ///
- /// let mut map = TrieMap::new();
- /// map.insert(1, "a");
- /// assert_eq!(map.find(&1), Some(&"a"));
- /// assert_eq!(map.find(&2), None);
- /// ```
- #[inline]
- pub 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;
- }
- }
-
- /// Returns true if the map contains a value for the specified key.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieMap;
- ///
- /// let mut map = TrieMap::new();
- /// map.insert(1, "a");
- /// assert_eq!(map.contains_key(&1), true);
- /// assert_eq!(map.contains_key(&2), false);
- /// ```
- #[inline]
- pub fn contains_key(&self, key: &uint) -> bool {
- self.find(key).is_some()
- }
-
- /// Returns a mutable reference to the value corresponding to the key.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieMap;
- ///
- /// let mut map = TrieMap::new();
- /// map.insert(1, "a");
- /// match map.find_mut(&1) {
- /// Some(x) => *x = "b",
- /// None => (),
- /// }
- /// assert_eq!(map[1], "b");
- /// ```
- #[inline]
- pub fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut T> {
- find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1)
- }
-
- /// Inserts a key-value pair into the map. An existing value for a
- /// key is replaced by the new value. Returns `true` if the key did
- /// not already exist in the map.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieMap;
- ///
- /// let mut map = TrieMap::new();
- /// assert_eq!(map.insert(2, "value"), true);
- /// assert_eq!(map.insert(2, "value2"), false);
- /// assert_eq!(map[2], "value2");
- /// ```
- #[inline]
- pub fn insert(&mut self, key: uint, value: T) -> bool {
- self.swap(key, value).is_none()
- }
-
- /// Removes a key-value pair from the map. Returns `true` if the key
- /// was present in the map.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieMap;
- ///
- /// let mut map = TrieMap::new();
- /// assert_eq!(map.remove(&1), false);
- /// map.insert(1, "a");
- /// assert_eq!(map.remove(&1), true);
- /// ```
- #[inline]
- pub fn remove(&mut self, key: &uint) -> bool {
- self.pop(key).is_some()
- }
-
- /// Inserts a key-value pair from the map. If the key already had a value
- /// present in the map, that value is returned. Otherwise, `None` is returned.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieMap;
- ///
- /// let mut map = TrieMap::new();
- /// assert_eq!(map.swap(37, "a"), None);
- /// assert_eq!(map.is_empty(), false);
- ///
- /// map.insert(37, "b");
- /// assert_eq!(map.swap(37, "c"), Some("b"));
- /// assert_eq!(map[37], "c");
- /// ```
- pub 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.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieMap;
- ///
- /// let mut map = TrieMap::new();
- /// map.insert(1, "a");
- /// assert_eq!(map.pop(&1), Some("a"));
- /// assert_eq!(map.pop(&1), None);
- /// ```
- pub 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
- }
-}
-
-// 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 evaluation as an expression. (see also
-// `item!` below.)
-macro_rules! addr { ($e:expr) => { $e } }
-
-macro_rules! bound {
- ($iterator_name:ident,
- // the current treemap
- self = $this:expr,
- // the key to look for
- key = $key:expr,
- // are we looking at the upper bound?
- is_upper = $upper:expr,
-
- // method names for slicing/iterating.
- slice_from = $slice_from:ident,
- iter = $iter:ident,
-
- // see the comment on `addr!`, this is just an optional mut, but
- // there's no 0-or-1 repeats yet.
- mutability = $($mut_:tt)*) => {
- {
- // # For `mut`
- // We need an unsafe pointer here because we are borrowing
- // mutable references to the internals of each of these
- // mutable nodes, while still using the outer node.
- //
- // However, we're allowed to flaunt rustc like this because we
- // never actually modify the "shape" of the nodes. The only
- // place that mutation is can actually occur is of the actual
- // values of the TrieMap (as the return value of the
- // iterator), i.e. we can never cause a deallocation of any
- // 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 = unsafe {
- mem::transmute::<_, uint>(&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 = unsafe {
- mem::transmute::<_, uint>(&**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_or_fail, iter = iter,
- mutability = )
- }
-
- /// Gets an iterator pointing to the first key-value pair whose key is not less than `key`.
- /// If all keys in the map are less than `key` an empty iterator is returned.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieMap;
- /// let map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect();
- ///
- /// assert_eq!(map.lower_bound(4).next(), Some((4, &"b")));
- /// assert_eq!(map.lower_bound(5).next(), Some((6, &"c")));
- /// assert_eq!(map.lower_bound(10).next(), None);
- /// ```
- pub fn lower_bound<'a>(&'a self, key: uint) -> Entries<'a, T> {
- self.bound(key, false)
- }
-
- /// Gets an iterator pointing to the first key-value pair whose key is greater than `key`.
- /// If all keys in the map are not greater than `key` an empty iterator is returned.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieMap;
- /// let map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect();
- ///
- /// assert_eq!(map.upper_bound(4).next(), Some((6, &"c")));
- /// assert_eq!(map.upper_bound(5).next(), Some((6, &"c")));
- /// assert_eq!(map.upper_bound(10).next(), None);
- /// ```
- pub fn upper_bound<'a>(&'a self, key: uint) -> Entries<'a, T> {
- self.bound(key, true)
- }
- // If `upper` is true then returns upper_bound else returns lower_bound.
- #[inline]
- fn bound_mut<'a>(&'a mut self, key: uint, upper: bool) -> MutEntries<'a, T> {
- bound!(MutEntries, self = self,
- key = key, is_upper = upper,
- slice_from = slice_from_or_fail_mut, iter = iter_mut,
- mutability = mut)
- }
-
- /// Gets an iterator pointing to the first key-value pair whose key is not less than `key`.
- /// If all keys in the map are less than `key` an empty iterator is returned.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieMap;
- /// let mut map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect();
- ///
- /// assert_eq!(map.lower_bound_mut(4).next(), Some((4, &mut "b")));
- /// assert_eq!(map.lower_bound_mut(5).next(), Some((6, &mut "c")));
- /// assert_eq!(map.lower_bound_mut(10).next(), None);
- ///
- /// for (key, value) in map.lower_bound_mut(4) {
- /// *value = "changed";
- /// }
- ///
- /// assert_eq!(map.find(&2), Some(&"a"));
- /// assert_eq!(map.find(&4), Some(&"changed"));
- /// assert_eq!(map.find(&6), Some(&"changed"));
- /// ```
- pub fn lower_bound_mut<'a>(&'a mut self, key: uint) -> MutEntries<'a, T> {
- self.bound_mut(key, false)
- }
-
- /// Gets an iterator pointing to the first key-value pair whose key is greater than `key`.
- /// If all keys in the map are not greater than `key` an empty iterator is returned.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieMap;
- /// let mut map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect();
- ///
- /// assert_eq!(map.upper_bound_mut(4).next(), Some((6, &mut "c")));
- /// assert_eq!(map.upper_bound_mut(5).next(), Some((6, &mut "c")));
- /// assert_eq!(map.upper_bound_mut(10).next(), None);
- ///
- /// for (key, value) in map.upper_bound_mut(4) {
- /// *value = "changed";
- /// }
- ///
- /// assert_eq!(map.find(&2), Some(&"a"));
- /// assert_eq!(map.find(&4), Some(&"b"));
- /// assert_eq!(map.find(&6), Some(&"changed"));
- /// ```
- pub fn upper_bound_mut<'a>(&'a mut self, key: uint) -> MutEntries<'a, T> {
- self.bound_mut(key, true)
- }
-}
-
-impl<T> FromIterator<(uint, T)> for TrieMap<T> {
- fn from_iter<Iter: Iterator<(uint, T)>>(iter: 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, mut iter: Iter) {
- for (k, v) in iter {
- self.insert(k, v);
- }
- }
-}
-
-impl<S: Writer, T: Hash<S>> Hash<S> for TrieMap<T> {
- fn hash(&self, state: &mut S) {
- for elt in self.iter() {
- elt.hash(state);
- }
- }
-}
-
-impl<T> Index<uint, T> for TrieMap<T> {
- #[inline]
- fn index<'a>(&'a self, i: &uint) -> &'a T {
- self.find(i).expect("key not present")
- }
-}
-
-impl<T> IndexMut<uint, T> for TrieMap<T> {
- #[inline]
- fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut T {
- self.find_mut(i).expect("key not present")
- }
-}
-
-/// A set implemented as a radix trie.
-///
-/// # Example
-///
-/// ```
-/// use std::collections::TrieSet;
-///
-/// let mut set = TrieSet::new();
-/// set.insert(6);
-/// set.insert(28);
-/// set.insert(6);
-///
-/// assert_eq!(set.len(), 2);
-///
-/// if !set.contains(&3) {
-/// println!("3 is not in the set");
-/// }
-///
-/// // Print contents in order
-/// for x in set.iter() {
-/// println!("{}", x);
-/// }
-///
-/// set.remove(&6);
-/// assert_eq!(set.len(), 1);
-///
-/// set.clear();
-/// assert!(set.is_empty());
-/// ```
-#[deriving(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
-pub struct TrieSet {
- map: TrieMap<()>
-}
-
-impl Show for TrieSet {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- try!(write!(f, "{{"));
-
- for (i, x) in self.iter().enumerate() {
- if i != 0 { try!(write!(f, ", ")); }
- try!(write!(f, "{}", x));
- }
-
- write!(f, "}}")
- }
-}
-
-impl Default for TrieSet {
- #[inline]
- fn default() -> TrieSet { TrieSet::new() }
-}
-
-impl TrieSet {
- /// Creates an empty TrieSet.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieSet;
- /// let mut set = TrieSet::new();
- /// ```
- #[inline]
- pub fn new() -> TrieSet {
- TrieSet{map: TrieMap::new()}
- }
-
- /// Visits all values in reverse order. Aborts traversal when `f` returns `false`.
- /// Returns `true` if `f` returns `true` for all elements.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieSet;
- ///
- /// let set: TrieSet = [1, 2, 3, 4, 5].iter().map(|&x| x).collect();
- ///
- /// let mut vec = Vec::new();
- /// assert_eq!(true, set.each_reverse(|&x| { vec.push(x); true }));
- /// assert_eq!(vec, vec![5, 4, 3, 2, 1]);
- ///
- /// // Stop when we reach 3
- /// let mut vec = Vec::new();
- /// assert_eq!(false, set.each_reverse(|&x| { vec.push(x); x != 3 }));
- /// assert_eq!(vec, vec![5, 4, 3]);
- /// ```
- #[inline]
- pub fn each_reverse(&self, f: |&uint| -> bool) -> bool {
- self.map.each_reverse(|k, _| f(k))
- }
-
- /// Gets an iterator over the values in the set, in sorted order.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieSet;
- ///
- /// let mut set = TrieSet::new();
- /// set.insert(3);
- /// set.insert(2);
- /// set.insert(1);
- /// set.insert(2);
- ///
- /// // Print 1, 2, 3
- /// for x in set.iter() {
- /// println!("{}", x);
- /// }
- /// ```
- #[inline]
- pub fn iter<'a>(&'a self) -> SetItems<'a> {
- SetItems{iter: self.map.iter()}
- }
-
- /// Gets an iterator pointing to the first value that is not less than `val`.
- /// If all values in the set are less than `val` an empty iterator is returned.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieSet;
- ///
- /// let set: TrieSet = [2, 4, 6, 8].iter().map(|&x| x).collect();
- /// assert_eq!(set.lower_bound(4).next(), Some(4));
- /// assert_eq!(set.lower_bound(5).next(), Some(6));
- /// assert_eq!(set.lower_bound(10).next(), None);
- /// ```
- pub fn lower_bound<'a>(&'a self, val: uint) -> SetItems<'a> {
- SetItems{iter: self.map.lower_bound(val)}
- }
-
- /// Gets an iterator pointing to the first value that key is greater than `val`.
- /// If all values in the set are less than or equal to `val` an empty iterator is returned.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieSet;
- ///
- /// let set: TrieSet = [2, 4, 6, 8].iter().map(|&x| x).collect();
- /// assert_eq!(set.upper_bound(4).next(), Some(6));
- /// assert_eq!(set.upper_bound(5).next(), Some(6));
- /// assert_eq!(set.upper_bound(10).next(), None);
- /// ```
- pub fn upper_bound<'a>(&'a self, val: uint) -> SetItems<'a> {
- SetItems{iter: self.map.upper_bound(val)}
- }
-
- /// Return the number of elements in the set
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieSet;
- ///
- /// let mut v = TrieSet::new();
- /// assert_eq!(v.len(), 0);
- /// v.insert(1);
- /// assert_eq!(v.len(), 1);
- /// ```
- #[inline]
- pub fn len(&self) -> uint { self.map.len() }
-
- /// Returns true if the set contains no elements
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieSet;
- ///
- /// let mut v = TrieSet::new();
- /// assert!(v.is_empty());
- /// v.insert(1);
- /// assert!(!v.is_empty());
- /// ```
- pub fn is_empty(&self) -> bool { self.len() == 0 }
-
- /// Clears the set, removing all values.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieSet;
- ///
- /// let mut v = TrieSet::new();
- /// v.insert(1);
- /// v.clear();
- /// assert!(v.is_empty());
- /// ```
- #[inline]
- pub fn clear(&mut self) { self.map.clear() }
-
- /// Returns `true` if the set contains a value.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieSet;
- ///
- /// let set: TrieSet = [1, 2, 3].iter().map(|&x| x).collect();
- /// assert_eq!(set.contains(&1), true);
- /// assert_eq!(set.contains(&4), false);
- /// ```
- #[inline]
- pub fn contains(&self, value: &uint) -> bool {
- self.map.contains_key(value)
- }
-
- /// Returns `true` if the set has no elements in common with `other`.
- /// This is equivalent to checking for an empty intersection.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieSet;
- ///
- /// let a: TrieSet = [1, 2, 3].iter().map(|&x| x).collect();
- /// let mut b: TrieSet = TrieSet::new();
- ///
- /// assert_eq!(a.is_disjoint(&b), true);
- /// b.insert(4);
- /// assert_eq!(a.is_disjoint(&b), true);
- /// b.insert(1);
- /// assert_eq!(a.is_disjoint(&b), false);
- /// ```
- #[inline]
- pub fn is_disjoint(&self, other: &TrieSet) -> bool {
- self.iter().all(|v| !other.contains(&v))
- }
-
- /// Returns `true` if the set is a subset of another.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieSet;
- ///
- /// let sup: TrieSet = [1, 2, 3].iter().map(|&x| x).collect();
- /// let mut set: TrieSet = TrieSet::new();
- ///
- /// assert_eq!(set.is_subset(&sup), true);
- /// set.insert(2);
- /// assert_eq!(set.is_subset(&sup), true);
- /// set.insert(4);
- /// assert_eq!(set.is_subset(&sup), false);
- /// ```
- #[inline]
- pub fn is_subset(&self, other: &TrieSet) -> bool {
- self.iter().all(|v| other.contains(&v))
- }
-
- /// Returns `true` if the set is a superset of another.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieSet;
- ///
- /// let sub: TrieSet = [1, 2].iter().map(|&x| x).collect();
- /// let mut set: TrieSet = TrieSet::new();
- ///
- /// assert_eq!(set.is_superset(&sub), false);
- ///
- /// set.insert(0);
- /// set.insert(1);
- /// assert_eq!(set.is_superset(&sub), false);
- ///
- /// set.insert(2);
- /// assert_eq!(set.is_superset(&sub), true);
- /// ```
- #[inline]
- pub fn is_superset(&self, other: &TrieSet) -> bool {
- other.is_subset(self)
- }
-
- /// Adds a value to the set. Returns `true` if the value was not already
- /// present in the set.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieSet;
- ///
- /// let mut set = TrieSet::new();
- ///
- /// assert_eq!(set.insert(2), true);
- /// assert_eq!(set.insert(2), false);
- /// assert_eq!(set.len(), 1);
- /// ```
- #[inline]
- pub fn insert(&mut self, value: uint) -> bool {
- self.map.insert(value, ())
- }
-
- /// Removes a value from the set. Returns `true` if the value was
- /// present in the set.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::TrieSet;
- ///
- /// let mut set = TrieSet::new();
- ///
- /// set.insert(2);
- /// assert_eq!(set.remove(&2), true);
- /// assert_eq!(set.remove(&2), false);
- /// ```
- #[inline]
- pub fn remove(&mut self, value: &uint) -> bool {
- self.map.remove(value)
- }
-}
-
-impl FromIterator<uint> for TrieSet {
- fn from_iter<Iter: Iterator<uint>>(iter: Iter) -> TrieSet {
- let mut set = TrieSet::new();
- set.extend(iter);
- set
- }
-}
-
-impl Extendable<uint> for TrieSet {
- fn extend<Iter: Iterator<uint>>(&mut self, mut iter: Iter) {
- for elem in iter {
- self.insert(elem);
- }
- }
-}
-
-struct TrieNode<T> {
- count: uint,
- children: [Child<T>, ..SIZE]
-}
-
-impl<T:Clone> Clone for TrieNode<T> {
- #[inline]
- fn clone(&self) -> TrieNode<T> {
- let ch = &self.children;
- TrieNode {
- count: self.count,
- children: [ch[0].clone(), ch[1].clone(), ch[2].clone(), ch[3].clone(),
- ch[4].clone(), ch[5].clone(), ch[6].clone(), ch[7].clone(),
- ch[8].clone(), ch[9].clone(), ch[10].clone(), ch[11].clone(),
- ch[12].clone(), ch[13].clone(), ch[14].clone(), ch[15].clone()]}
- }
-}
-
-impl<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.iter().rev() {
- match *elt {
- Internal(ref x) => if !x.each_reverse(|i,t| f(i,t)) { return false },
- External(k, ref v) => if !f(&k, v) { return false },
- Nothing => ()
- }
- }
- true
- }
-}
-
-// if this was done via a trait, the key could be generic
-#[inline]
-fn chunk(n: uint, idx: uint) -> uint {
- let sh = uint::BITS - (SHIFT * (idx + 1));
- (n >> sh) & MASK
-}
-
-fn find_mut<'r, T>(child: &'r mut 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(box ref mut x) => {
- return insert(&mut x.count, &mut x.children[chunk(key, idx)], key, value, idx + 1);
- }
- External(stored_key, ref mut stored_value) if stored_key == key => {
- // swap in the new value and return the old.
- 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 = box TrieNode::new();
-
- let ret = {
- let new_interior = &mut *new;
- insert(&mut new_interior.count,
- &mut new_interior.children[chunk(stored_key, idx)],
- stored_key, stored_value, idx + 1);
- insert(&mut new_interior.count,
- &mut new_interior.children[chunk(key, idx)],
- key, value, idx + 1)
- };
-
- *child = Internal(new);
- return ret;
- }
- _ => panic!("unreachable code"),
- }
-}
-
-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),
- _ => panic!()
- }
- }
- External(..) => (None, false),
- Internal(box ref mut x) => {
- let ret = remove(&mut x.count, &mut x.children[chunk(key, idx)],
- key, idx + 1);
- (ret, x.count == 0)
- }
- Nothing => (None, false)
- };
-
- if this {
- *child = Nothing;
- *count -= 1;
- }
- return ret;
-}
-
-/// A forward iterator over a map.
-pub struct Entries<'a, T:'a> {
- stack: [slice::Items<'a, Child<T>>, .. NUM_CHUNKS],
- length: uint,
- remaining_min: uint,
- remaining_max: uint
-}
-
-/// A forward iterator over the key-value pairs of a map, with the
-/// values being mutable.
-pub struct MutEntries<'a, T:'a> {
- stack: [slice::MutItems<'a, Child<T>>, .. NUM_CHUNKS],
- length: uint,
- remaining_min: uint,
- remaining_max: uint
-}
-
-/// A forward iterator over the keys of a map.
-pub type Keys<'a, T> =
- iter::Map<'static, (uint, &'a T), uint, Entries<'a, T>>;
-
-/// A forward iterator over the values of a map.
-pub type Values<'a, T> =
- iter::Map<'static, (uint, &'a T), &'a T, Entries<'a, T>>;
-
-// FIXME #5846: see `addr!` above.
-macro_rules! item { ($i:item) => {$i}}
-
-macro_rules! iterator_impl {
- ($name:ident,
- iter = $iter:ident,
- mutability = $($mut_:tt)*) => {
- impl<'a, T> $name<'a, T> {
- // Create new zero'd iterator. We have a thin gilding of safety by
- // using init rather than uninit, so that the worst that can happen
- // from failing to initialise correctly after calling these is a
- // segfault.
- #[cfg(target_word_size="32")]
- unsafe fn new() -> $name<'a, T> {
- $name {
- remaining_min: 0,
- remaining_max: 0,
- length: 0,
- // ick :( ... at least the compiler will tell us if we screwed up.
- stack: [zeroed(), zeroed(), zeroed(), zeroed(), zeroed(),
- zeroed(), zeroed(), zeroed()]
- }
- }
-
- #[cfg(target_word_size="64")]
- unsafe fn new() -> $name<'a, T> {
- $name {
- remaining_min: 0,
- remaining_max: 0,
- length: 0,
- stack: [zeroed(), zeroed(), zeroed(), zeroed(),
- zeroed(), zeroed(), zeroed(), zeroed(),
- zeroed(), zeroed(), zeroed(), zeroed(),
- zeroed(), zeroed(), zeroed(), zeroed()]
- }
- }
- }
-
- item!(impl<'a, T> Iterator<(uint, &'a $($mut_)* T)> for $name<'a, T> {
- // you might wonder why we're not even trying to act within the
- // rules, and are just manipulating raw pointers like there's no
- // such thing as invalid pointers and memory unsafety. The
- // reason is performance, without doing this we can get the
- // (now replaced) bench_iter_large microbenchmark down to about
- // 30000 ns/iter (using .unsafe_get to index self.stack directly, 38000
- // ns/iter with [] checked indexing), but this smashes that down
- // to 13500 ns/iter.
- //
- // Fortunately, it's still safe...
- //
- // We have an invariant that every Internal node
- // corresponds to one push to self.stack, and one pop,
- // nested appropriately. self.stack has enough storage
- // to store the maximum depth of Internal nodes in the
- // trie (8 on 32-bit platforms, 16 on 64-bit).
- fn next(&mut self) -> Option<(uint, &'a $($mut_)* T)> {
- let start_ptr = self.stack.as_mut_ptr();
-
- unsafe {
- // write_ptr is the next place to write to the stack.
- // invariant: start_ptr <= write_ptr < end of the
- // vector.
- let mut write_ptr = start_ptr.offset(self.length as int);
- while write_ptr != start_ptr {
- // indexing back one is safe, since write_ptr >
- // start_ptr now.
- match (*write_ptr.offset(-1)).next() {
- // exhausted this iterator (i.e. finished this
- // Internal node), so pop from the stack.
- //
- // don't bother clearing the memory, because the
- // next time we use it we'll've written to it
- // first.
- None => write_ptr = write_ptr.offset(-1),
- Some(child) => {
- addr!(match *child {
- Internal(ref $($mut_)* node) => {
- // going down a level, so push
- // to the stack (this is the
- // write referenced above)
- *write_ptr = node.children.$iter();
- write_ptr = write_ptr.offset(1);
- }
- External(key, ref $($mut_)* value) => {
- self.remaining_max -= 1;
- if self.remaining_min > 0 {
- self.remaining_min -= 1;
- }
- // store the new length of the
- // stack, based on our current
- // position.
- self.length = (write_ptr as uint
- - start_ptr as uint) /
- mem::size_of_val(&*write_ptr);
-
- return Some((key, value));
- }
- Nothing => {}
- })
- }
- }
- }
- }
- return None;
- }
-
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- (self.remaining_min, Some(self.remaining_max))
- }
- })
- }
-}
-
-iterator_impl! { Entries, iter = iter, mutability = }
-iterator_impl! { MutEntries, iter = iter_mut, mutability = mut }
-
-/// A forward iterator over a set.
-pub struct SetItems<'a> {
- 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)]
-mod test_map {
- use std::prelude::*;
- use std::iter::range_step;
- use std::uint;
- use std::hash;
-
- use super::{TrieMap, TrieNode, Internal, External, Nothing};
-
- 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(1u, 12i));
- assert!(m.insert(2u, 8i));
- assert!(m.insert(5u, 14i));
- let new = 100;
- match m.find_mut(&5) {
- None => panic!(), 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(1u, 12i));
- 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(1u, 2i), None);
- assert_eq!(m.swap(1u, 3i), Some(2));
- assert_eq!(m.swap(1u, 4i), Some(3));
- }
-
- #[test]
- fn test_pop() {
- let mut m = TrieMap::new();
- m.insert(1u, 2i);
- assert_eq!(m.pop(&1), Some(2));
- assert_eq!(m.pop(&1), None);
- }
-
- #[test]
- fn test_from_iter() {
- let xs = vec![(1u, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
- let map: TrieMap<int> = xs.iter().map(|&x| x).collect();
-
- for &(k, v) in xs.iter() {
- assert_eq!(map.find(&k), Some(&v));
- }
- }
-
- #[test]
- fn test_keys() {
- let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
- let map = vec.into_iter().collect::<TrieMap<char>>();
- let keys = map.keys().collect::<Vec<uint>>();
- assert_eq!(keys.len(), 3);
- assert!(keys.contains(&1));
- assert!(keys.contains(&2));
- assert!(keys.contains(&3));
- }
-
- #[test]
- fn test_values() {
- let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
- let map = vec.into_iter().collect::<TrieMap<char>>();
- let values = map.values().map(|&v| v).collect::<Vec<char>>();
- assert_eq!(values.len(), 3);
- assert!(values.contains(&'a'));
- assert!(values.contains(&'b'));
- assert!(values.contains(&'c'));
- }
-
- #[test]
- fn test_iteration() {
- let empty_map : TrieMap<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.iter_mut().next().is_none());
-
- let first = uint::MAX - 10000;
- let last = uint::MAX;
-
- let mut map = TrieMap::new();
- for x in range(first, last).rev() {
- map.insert(x, x / 2);
- }
-
- let mut i = 0;
- for (k, v) in map.iter_mut() {
- assert_eq!(k, first + i);
- *v -= k / 2;
- i += 1;
- }
- assert_eq!(i, last - first);
-
- assert!(map.iter().all(|(_, &v)| v == 0));
- }
-
- #[test]
- fn test_bound() {
- let empty_map : TrieMap<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.lower_bound_mut(i);
- let (k, v) = lb_it.next().unwrap();
- let lb = i + i % 2;
- assert_eq!(lb, k);
- *v -= k;
- }
-
- for i in range(0u, 198) {
- let mut ub_it = m_upper.upper_bound_mut(i);
- let (k, v) = ub_it.next().unwrap();
- let ub = i + 2 - i % 2;
- assert_eq!(ub, k);
- *v -= k;
- }
-
- assert!(m_lower.lower_bound_mut(199).next().is_none());
- assert!(m_upper.upper_bound_mut(198).next().is_none());
-
- assert!(m_lower.iter().all(|(_, &x)| x == 0));
- assert!(m_upper.iter().all(|(_, &x)| x == 0));
- }
-
- #[test]
- fn test_clone() {
- let mut a = TrieMap::new();
-
- a.insert(1, 'a');
- a.insert(2, 'b');
- a.insert(3, 'c');
-
- assert!(a.clone() == a);
- }
-
- #[test]
- fn test_eq() {
- let mut a = TrieMap::new();
- let mut b = TrieMap::new();
-
- assert!(a == b);
- assert!(a.insert(0, 5i));
- assert!(a != b);
- assert!(b.insert(0, 4i));
- assert!(a != b);
- assert!(a.insert(5, 19));
- assert!(a != b);
- assert!(!b.insert(0, 5));
- assert!(a != b);
- assert!(b.insert(5, 19));
- assert!(a == b);
- }
-
- #[test]
- fn test_lt() {
- let mut a = TrieMap::new();
- let mut b = TrieMap::new();
-
- assert!(!(a < b) && !(b < a));
- assert!(b.insert(2u, 5i));
- assert!(a < b);
- assert!(a.insert(2, 7));
- assert!(!(a < b) && b < a);
- assert!(b.insert(1, 0));
- assert!(b < a);
- assert!(a.insert(0, 6));
- assert!(a < b);
- assert!(a.insert(6, 2));
- assert!(a < b && !(b < a));
- }
-
- #[test]
- fn test_ord() {
- let mut a = TrieMap::new();
- let mut b = TrieMap::new();
-
- assert!(a <= b && a >= b);
- assert!(a.insert(1u, 1i));
- assert!(a > b && a >= b);
- assert!(b < a && b <= a);
- assert!(b.insert(2, 2));
- assert!(b > a && b >= a);
- assert!(a < b && a <= b);
- }
-
- #[test]
- fn test_hash() {
- let mut x = TrieMap::new();
- let mut y = TrieMap::new();
-
- assert!(hash::hash(&x) == hash::hash(&y));
- x.insert(1, 'a');
- x.insert(2, 'b');
- x.insert(3, 'c');
-
- y.insert(3, 'c');
- y.insert(2, 'b');
- y.insert(1, 'a');
-
- assert!(hash::hash(&x) == hash::hash(&y));
- }
-
- #[test]
- fn test_show() {
- let mut map = TrieMap::new();
- let empty: TrieMap<uint> = TrieMap::new();
-
- map.insert(1, 'a');
- map.insert(2, 'b');
-
- let map_str = format!("{}", map);
-
- assert!(map_str == "{1: a, 2: b}".to_string());
- assert_eq!(format!("{}", empty), "{}".to_string());
- }
-
- #[test]
- fn test_index() {
- let mut map = TrieMap::new();
-
- map.insert(1, 2i);
- map.insert(2, 1i);
- map.insert(3, 4i);
-
- assert_eq!(map[2], 1);
- }
-
- #[test]
- #[should_fail]
- fn test_index_nonexistent() {
- let mut map = TrieMap::new();
-
- map.insert(1, 2i);
- map.insert(2, 1i);
- map.insert(3, 4i);
-
- map[4];
- }
-}
-
-#[cfg(test)]
-mod bench_map {
- use std::prelude::*;
- use std::rand::{weak_rng, Rng};
- use test::{Bencher, black_box};
-
- use super::TrieMap;
-
- fn bench_iter(b: &mut Bencher, size: uint) {
- let mut map = TrieMap::<uint>::new();
- let mut rng = weak_rng();
-
- for _ in range(0, size) {
- map.swap(rng.gen(), rng.gen());
- }
-
- b.iter(|| {
- for entry in map.iter() {
- black_box(entry);
- }
- });
- }
-
- #[bench]
- pub fn iter_20(b: &mut Bencher) {
- bench_iter(b, 20);
- }
-
- #[bench]
- pub fn iter_1000(b: &mut Bencher) {
- bench_iter(b, 1000);
- }
-
- #[bench]
- pub fn iter_100000(b: &mut Bencher) {
- bench_iter(b, 100000);
- }
-
- #[bench]
- fn bench_lower_bound(b: &mut Bencher) {
- let mut m = TrieMap::<uint>::new();
- let mut rng = weak_rng();
- for _ in range(0u, 1000) {
- m.insert(rng.gen(), rng.gen());
- }
-
- b.iter(|| {
- for _ in range(0u, 10) {
- m.lower_bound(rng.gen());
- }
- });
- }
-
- #[bench]
- fn bench_upper_bound(b: &mut Bencher) {
- let mut m = TrieMap::<uint>::new();
- let mut rng = weak_rng();
- for _ in range(0u, 1000) {
- m.insert(rng.gen(), rng.gen());
- }
-
- b.iter(|| {
- for _ in range(0u, 10) {
- m.upper_bound(rng.gen());
- }
- });
- }
-
- #[bench]
- fn bench_insert_large(b: &mut Bencher) {
- let mut m = TrieMap::<[uint, .. 10]>::new();
- let mut rng = weak_rng();
-
- b.iter(|| {
- for _ in range(0u, 1000) {
- m.insert(rng.gen(), [1, .. 10]);
- }
- })
- }
- #[bench]
- fn bench_insert_large_low_bits(b: &mut Bencher) {
- let mut m = TrieMap::<[uint, .. 10]>::new();
- let mut rng = weak_rng();
-
- b.iter(|| {
- for _ in range(0u, 1000) {
- // only have the last few bits set.
- m.insert(rng.gen::<uint>() & 0xff_ff, [1, .. 10]);
- }
- })
- }
-
- #[bench]
- fn bench_insert_small(b: &mut Bencher) {
- let mut m = TrieMap::<()>::new();
- let mut rng = weak_rng();
-
- b.iter(|| {
- for _ in range(0u, 1000) {
- m.insert(rng.gen(), ());
- }
- })
- }
- #[bench]
- fn bench_insert_small_low_bits(b: &mut Bencher) {
- let mut m = TrieMap::<()>::new();
- let mut rng = weak_rng();
-
- b.iter(|| {
- for _ in range(0u, 1000) {
- // only have the last few bits set.
- m.insert(rng.gen::<uint>() & 0xff_ff, ());
- }
- })
- }
-}
-
-#[cfg(test)]
-mod test_set {
- use std::prelude::*;
- use std::uint;
-
- use super::TrieSet;
-
- #[test]
- fn test_sane_chunk() {
- let x = 1;
- let y = 1 << (uint::BITS - 1);
-
- let mut trie = TrieSet::new();
-
- assert!(trie.insert(x));
- assert!(trie.insert(y));
-
- assert_eq!(trie.len(), 2);
-
- let expected = [x, y];
-
- for (i, x) in trie.iter().enumerate() {
- assert_eq!(expected[i], x);
- }
- }
-
- #[test]
- fn test_from_iter() {
- let xs = vec![9u, 8, 7, 6, 5, 4, 3, 2, 1];
-
- let set: TrieSet = xs.iter().map(|&x| x).collect();
-
- for x in xs.iter() {
- assert!(set.contains(x));
- }
- }
-
- #[test]
- fn test_show() {
- let mut set = TrieSet::new();
- let empty = TrieSet::new();
-
- set.insert(1);
- set.insert(2);
-
- let set_str = format!("{}", set);
-
- assert!(set_str == "{1, 2}".to_string());
- assert_eq!(format!("{}", empty), "{}".to_string());
- }
-
- #[test]
- fn test_clone() {
- let mut a = TrieSet::new();
-
- a.insert(1);
- a.insert(2);
- a.insert(3);
-
- assert!(a.clone() == a);
- }
-
- #[test]
- fn test_lt() {
- let mut a = TrieSet::new();
- let mut b = TrieSet::new();
-
- assert!(!(a < b) && !(b < a));
- assert!(b.insert(2u));
- assert!(a < b);
- assert!(a.insert(3u));
- assert!(!(a < b) && b < a);
- assert!(b.insert(1));
- assert!(b < a);
- assert!(a.insert(0));
- assert!(a < b);
- assert!(a.insert(6));
- assert!(a < b && !(b < a));
- }
-
- #[test]
- fn test_ord() {
- let mut a = TrieSet::new();
- let mut b = TrieSet::new();
-
- assert!(a <= b && a >= b);
- assert!(a.insert(1u));
- assert!(a > b && a >= b);
- assert!(b < a && b <= a);
- assert!(b.insert(2u));
- assert!(b > a && b >= a);
- assert!(a < b && a <= b);
- }
-}
--- /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.
+
+//! Maps are collections of unique keys with corresponding values, and sets are
+//! just unique keys without a corresponding value. The `Map` and `Set` traits in
+//! `std::container` define the basic interface.
+//!
+//! This crate defines `TrieMap` and `TrieSet`, which require `uint` keys.
+//!
+//! `TrieMap` is ordered.
+
+use core::prelude::*;
+
+use alloc::boxed::Box;
+use core::default::Default;
+use core::fmt;
+use core::fmt::Show;
+use core::mem::zeroed;
+use core::mem;
+use core::ops::{Slice,SliceMut};
+use core::uint;
+use core::iter;
+use std::hash::{Writer, Hash};
+
+use slice::{Items, MutItems};
+use slice;
+
+// FIXME: #5244: need to manually update the TrieNode constructor
+const SHIFT: uint = 4;
+const SIZE: uint = 1 << SHIFT;
+const MASK: uint = SIZE - 1;
+const NUM_CHUNKS: uint = uint::BITS / SHIFT;
+
+#[deriving(Clone)]
+enum Child<T> {
+ Internal(Box<TrieNode<T>>),
+ External(uint, T),
+ Nothing
+}
+
+/// A map implemented as a radix trie.
+///
+/// # Example
+///
+/// ```
+/// use std::collections::TrieMap;
+///
+/// let mut map = TrieMap::new();
+/// map.insert(27, "Olaf");
+/// map.insert(1, "Edgar");
+/// map.insert(13, "Ruth");
+/// map.insert(1, "Martin");
+///
+/// assert_eq!(map.len(), 3);
+/// assert_eq!(map.find(&1), Some(&"Martin"));
+///
+/// if !map.contains_key(&90) {
+/// println!("Nobody is keyed 90");
+/// }
+///
+/// // Update a key
+/// match map.find_mut(&1) {
+/// Some(value) => *value = "Olga",
+/// None => (),
+/// }
+///
+/// map.remove(&13);
+/// assert_eq!(map.len(), 2);
+///
+/// // Print the key value pairs, ordered by key.
+/// for (key, value) in map.iter() {
+/// // Prints `1: Olga` then `27: Olaf`
+/// println!("{}: {}", key, value);
+/// }
+///
+/// map.clear();
+/// assert!(map.is_empty());
+/// ```
+#[deriving(Clone)]
+pub struct TrieMap<T> {
+ root: TrieNode<T>,
+ length: uint
+}
+
+impl<T: PartialEq> PartialEq for TrieMap<T> {
+ fn eq(&self, other: &TrieMap<T>) -> bool {
+ self.len() == other.len() &&
+ self.iter().zip(other.iter()).all(|(a, b)| a == b)
+ }
+}
+
+impl<T: Eq> Eq for TrieMap<T> {}
+
+impl<T: PartialOrd> PartialOrd for TrieMap<T> {
+ #[inline]
+ fn partial_cmp(&self, other: &TrieMap<T>) -> Option<Ordering> {
+ iter::order::partial_cmp(self.iter(), other.iter())
+ }
+}
+
+impl<T: Ord> Ord for TrieMap<T> {
+ #[inline]
+ fn cmp(&self, other: &TrieMap<T>) -> Ordering {
+ iter::order::cmp(self.iter(), other.iter())
+ }
+}
+
+impl<T: Show> Show for TrieMap<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ try!(write!(f, "{{"));
+
+ for (i, (k, v)) in self.iter().enumerate() {
+ if i != 0 { try!(write!(f, ", ")); }
+ try!(write!(f, "{}: {}", k, *v));
+ }
+
+ write!(f, "}}")
+ }
+}
+
+impl<T> Default for TrieMap<T> {
+ #[inline]
+ fn default() -> TrieMap<T> { TrieMap::new() }
+}
+
+impl<T> TrieMap<T> {
+ /// Creates an empty `TrieMap`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ /// let mut map: TrieMap<&str> = TrieMap::new();
+ /// ```
+ #[inline]
+ pub fn new() -> TrieMap<T> {
+ TrieMap{root: TrieNode::new(), length: 0}
+ }
+
+ /// Visits all key-value pairs in reverse order. Aborts traversal when `f` returns `false`.
+ /// Returns `true` if `f` returns `true` for all elements.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ /// let map: TrieMap<&str> = [(1, "a"), (2, "b"), (3, "c")].iter().map(|&x| x).collect();
+ ///
+ /// let mut vec = Vec::new();
+ /// assert_eq!(true, map.each_reverse(|&key, &value| { vec.push((key, value)); true }));
+ /// assert_eq!(vec, vec![(3, "c"), (2, "b"), (1, "a")]);
+ ///
+ /// // Stop when we reach 2
+ /// let mut vec = Vec::new();
+ /// assert_eq!(false, map.each_reverse(|&key, &value| { vec.push(value); key != 2 }));
+ /// assert_eq!(vec, vec!["c", "b"]);
+ /// ```
+ #[inline]
+ pub fn each_reverse<'a>(&'a self, f: |&uint, &'a T| -> bool) -> bool {
+ self.root.each_reverse(f)
+ }
+
+ /// Gets an iterator visiting all keys in ascending order by the keys.
+ /// The iterator's element type is `uint`.
+ pub fn keys<'r>(&'r self) -> Keys<'r, T> {
+ self.iter().map(|(k, _v)| k)
+ }
+
+ /// Gets an iterator visiting all values in ascending order by the keys.
+ /// The iterator's element type is `&'r T`.
+ pub fn values<'r>(&'r self) -> Values<'r, T> {
+ self.iter().map(|(_k, v)| v)
+ }
+
+ /// Gets an iterator over the key-value pairs in the map, ordered by keys.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ /// let map: TrieMap<&str> = [(3, "c"), (1, "a"), (2, "b")].iter().map(|&x| x).collect();
+ ///
+ /// for (key, value) in map.iter() {
+ /// println!("{}: {}", key, value);
+ /// }
+ /// ```
+ pub fn iter<'a>(&'a self) -> Entries<'a, T> {
+ let mut iter = unsafe {Entries::new()};
+ iter.stack[0] = self.root.children.iter();
+ iter.length = 1;
+ iter.remaining_min = self.length;
+ iter.remaining_max = self.length;
+
+ iter
+ }
+
+ /// Gets an iterator over the key-value pairs in the map, with the
+ /// ability to mutate the values.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ /// let mut map: TrieMap<int> = [(1, 2), (2, 4), (3, 6)].iter().map(|&x| x).collect();
+ ///
+ /// for (key, value) in map.iter_mut() {
+ /// *value = -(key as int);
+ /// }
+ ///
+ /// assert_eq!(map.find(&1), Some(&-1));
+ /// assert_eq!(map.find(&2), Some(&-2));
+ /// assert_eq!(map.find(&3), Some(&-3));
+ /// ```
+ pub fn iter_mut<'a>(&'a mut self) -> MutEntries<'a, T> {
+ let mut iter = unsafe {MutEntries::new()};
+ iter.stack[0] = self.root.children.iter_mut();
+ iter.length = 1;
+ iter.remaining_min = self.length;
+ iter.remaining_max = self.length;
+
+ iter
+ }
+
+ /// Return the number of elements in the map.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ ///
+ /// let mut a = TrieMap::new();
+ /// assert_eq!(a.len(), 0);
+ /// a.insert(1, "a");
+ /// assert_eq!(a.len(), 1);
+ /// ```
+ #[inline]
+ pub fn len(&self) -> uint { self.length }
+
+ /// Return true if the map contains no elements.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ ///
+ /// let mut a = TrieMap::new();
+ /// assert!(a.is_empty());
+ /// a.insert(1, "a");
+ /// assert!(!a.is_empty());
+ /// ```
+ #[inline]
+ pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+ /// Clears the map, removing all values.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ ///
+ /// let mut a = TrieMap::new();
+ /// a.insert(1, "a");
+ /// a.clear();
+ /// assert!(a.is_empty());
+ /// ```
+ #[inline]
+ pub fn clear(&mut self) {
+ self.root = TrieNode::new();
+ self.length = 0;
+ }
+
+ /// Returns a reference to the value corresponding to the key.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ ///
+ /// let mut map = TrieMap::new();
+ /// map.insert(1, "a");
+ /// assert_eq!(map.find(&1), Some(&"a"));
+ /// assert_eq!(map.find(&2), None);
+ /// ```
+ #[inline]
+ pub 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;
+ }
+ }
+
+ /// Returns true if the map contains a value for the specified key.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ ///
+ /// let mut map = TrieMap::new();
+ /// map.insert(1, "a");
+ /// assert_eq!(map.contains_key(&1), true);
+ /// assert_eq!(map.contains_key(&2), false);
+ /// ```
+ #[inline]
+ pub fn contains_key(&self, key: &uint) -> bool {
+ self.find(key).is_some()
+ }
+
+ /// Returns a mutable reference to the value corresponding to the key.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ ///
+ /// let mut map = TrieMap::new();
+ /// map.insert(1, "a");
+ /// match map.find_mut(&1) {
+ /// Some(x) => *x = "b",
+ /// None => (),
+ /// }
+ /// assert_eq!(map[1], "b");
+ /// ```
+ #[inline]
+ pub fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut T> {
+ find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1)
+ }
+
+ /// Inserts a key-value pair into the map. An existing value for a
+ /// key is replaced by the new value. Returns `true` if the key did
+ /// not already exist in the map.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ ///
+ /// let mut map = TrieMap::new();
+ /// assert_eq!(map.insert(2, "value"), true);
+ /// assert_eq!(map.insert(2, "value2"), false);
+ /// assert_eq!(map[2], "value2");
+ /// ```
+ #[inline]
+ pub fn insert(&mut self, key: uint, value: T) -> bool {
+ self.swap(key, value).is_none()
+ }
+
+ /// Removes a key-value pair from the map. Returns `true` if the key
+ /// was present in the map.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ ///
+ /// let mut map = TrieMap::new();
+ /// assert_eq!(map.remove(&1), false);
+ /// map.insert(1, "a");
+ /// assert_eq!(map.remove(&1), true);
+ /// ```
+ #[inline]
+ pub fn remove(&mut self, key: &uint) -> bool {
+ self.pop(key).is_some()
+ }
+
+ /// Inserts a key-value pair from the map. If the key already had a value
+ /// present in the map, that value is returned. Otherwise, `None` is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ ///
+ /// let mut map = TrieMap::new();
+ /// assert_eq!(map.swap(37, "a"), None);
+ /// assert_eq!(map.is_empty(), false);
+ ///
+ /// map.insert(37, "b");
+ /// assert_eq!(map.swap(37, "c"), Some("b"));
+ /// assert_eq!(map[37], "c");
+ /// ```
+ pub 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.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ ///
+ /// let mut map = TrieMap::new();
+ /// map.insert(1, "a");
+ /// assert_eq!(map.pop(&1), Some("a"));
+ /// assert_eq!(map.pop(&1), None);
+ /// ```
+ pub 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
+ }
+}
+
+// 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 evaluation as an expression. (see also
+// `item!` below.)
+macro_rules! addr { ($e:expr) => { $e } }
+
+macro_rules! bound {
+ ($iterator_name:ident,
+ // the current treemap
+ self = $this:expr,
+ // the key to look for
+ key = $key:expr,
+ // are we looking at the upper bound?
+ is_upper = $upper:expr,
+
+ // method names for slicing/iterating.
+ slice_from = $slice_from:ident,
+ iter = $iter:ident,
+
+ // see the comment on `addr!`, this is just an optional mut, but
+ // there's no 0-or-1 repeats yet.
+ mutability = $($mut_:tt)*) => {
+ {
+ // # For `mut`
+ // We need an unsafe pointer here because we are borrowing
+ // mutable references to the internals of each of these
+ // mutable nodes, while still using the outer node.
+ //
+ // However, we're allowed to flaunt rustc like this because we
+ // never actually modify the "shape" of the nodes. The only
+ // place that mutation is can actually occur is of the actual
+ // values of the TrieMap (as the return value of the
+ // iterator), i.e. we can never cause a deallocation of any
+ // 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 = unsafe {
+ mem::transmute::<_, uint>(&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 = unsafe {
+ mem::transmute::<_, uint>(&**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_or_fail, iter = iter,
+ mutability = )
+ }
+
+ /// Gets an iterator pointing to the first key-value pair whose key is not less than `key`.
+ /// If all keys in the map are less than `key` an empty iterator is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ /// let map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect();
+ ///
+ /// assert_eq!(map.lower_bound(4).next(), Some((4, &"b")));
+ /// assert_eq!(map.lower_bound(5).next(), Some((6, &"c")));
+ /// assert_eq!(map.lower_bound(10).next(), None);
+ /// ```
+ pub fn lower_bound<'a>(&'a self, key: uint) -> Entries<'a, T> {
+ self.bound(key, false)
+ }
+
+ /// Gets an iterator pointing to the first key-value pair whose key is greater than `key`.
+ /// If all keys in the map are not greater than `key` an empty iterator is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ /// let map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect();
+ ///
+ /// assert_eq!(map.upper_bound(4).next(), Some((6, &"c")));
+ /// assert_eq!(map.upper_bound(5).next(), Some((6, &"c")));
+ /// assert_eq!(map.upper_bound(10).next(), None);
+ /// ```
+ pub fn upper_bound<'a>(&'a self, key: uint) -> Entries<'a, T> {
+ self.bound(key, true)
+ }
+ // If `upper` is true then returns upper_bound else returns lower_bound.
+ #[inline]
+ fn bound_mut<'a>(&'a mut self, key: uint, upper: bool) -> MutEntries<'a, T> {
+ bound!(MutEntries, self = self,
+ key = key, is_upper = upper,
+ slice_from = slice_from_or_fail_mut, iter = iter_mut,
+ mutability = mut)
+ }
+
+ /// Gets an iterator pointing to the first key-value pair whose key is not less than `key`.
+ /// If all keys in the map are less than `key` an empty iterator is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ /// let mut map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect();
+ ///
+ /// assert_eq!(map.lower_bound_mut(4).next(), Some((4, &mut "b")));
+ /// assert_eq!(map.lower_bound_mut(5).next(), Some((6, &mut "c")));
+ /// assert_eq!(map.lower_bound_mut(10).next(), None);
+ ///
+ /// for (key, value) in map.lower_bound_mut(4) {
+ /// *value = "changed";
+ /// }
+ ///
+ /// assert_eq!(map.find(&2), Some(&"a"));
+ /// assert_eq!(map.find(&4), Some(&"changed"));
+ /// assert_eq!(map.find(&6), Some(&"changed"));
+ /// ```
+ pub fn lower_bound_mut<'a>(&'a mut self, key: uint) -> MutEntries<'a, T> {
+ self.bound_mut(key, false)
+ }
+
+ /// Gets an iterator pointing to the first key-value pair whose key is greater than `key`.
+ /// If all keys in the map are not greater than `key` an empty iterator is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieMap;
+ /// let mut map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect();
+ ///
+ /// assert_eq!(map.upper_bound_mut(4).next(), Some((6, &mut "c")));
+ /// assert_eq!(map.upper_bound_mut(5).next(), Some((6, &mut "c")));
+ /// assert_eq!(map.upper_bound_mut(10).next(), None);
+ ///
+ /// for (key, value) in map.upper_bound_mut(4) {
+ /// *value = "changed";
+ /// }
+ ///
+ /// assert_eq!(map.find(&2), Some(&"a"));
+ /// assert_eq!(map.find(&4), Some(&"b"));
+ /// assert_eq!(map.find(&6), Some(&"changed"));
+ /// ```
+ pub fn upper_bound_mut<'a>(&'a mut self, key: uint) -> MutEntries<'a, T> {
+ self.bound_mut(key, true)
+ }
+}
+
+impl<T> FromIterator<(uint, T)> for TrieMap<T> {
+ fn from_iter<Iter: Iterator<(uint, T)>>(iter: 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, mut iter: Iter) {
+ for (k, v) in iter {
+ self.insert(k, v);
+ }
+ }
+}
+
+impl<S: Writer, T: Hash<S>> Hash<S> for TrieMap<T> {
+ fn hash(&self, state: &mut S) {
+ for elt in self.iter() {
+ elt.hash(state);
+ }
+ }
+}
+
+impl<T> Index<uint, T> for TrieMap<T> {
+ #[inline]
+ fn index<'a>(&'a self, i: &uint) -> &'a T {
+ self.find(i).expect("key not present")
+ }
+}
+
+impl<T> IndexMut<uint, T> for TrieMap<T> {
+ #[inline]
+ fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut T {
+ self.find_mut(i).expect("key not present")
+ }
+}
+
+struct TrieNode<T> {
+ count: uint,
+ children: [Child<T>, ..SIZE]
+}
+
+impl<T:Clone> Clone for TrieNode<T> {
+ #[inline]
+ fn clone(&self) -> TrieNode<T> {
+ let ch = &self.children;
+ TrieNode {
+ count: self.count,
+ children: [ch[0].clone(), ch[1].clone(), ch[2].clone(), ch[3].clone(),
+ ch[4].clone(), ch[5].clone(), ch[6].clone(), ch[7].clone(),
+ ch[8].clone(), ch[9].clone(), ch[10].clone(), ch[11].clone(),
+ ch[12].clone(), ch[13].clone(), ch[14].clone(), ch[15].clone()]}
+ }
+}
+
+impl<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.iter().rev() {
+ match *elt {
+ Internal(ref x) => if !x.each_reverse(|i,t| f(i,t)) { return false },
+ External(k, ref v) => if !f(&k, v) { return false },
+ Nothing => ()
+ }
+ }
+ true
+ }
+}
+
+// if this was done via a trait, the key could be generic
+#[inline]
+fn chunk(n: uint, idx: uint) -> uint {
+ let sh = uint::BITS - (SHIFT * (idx + 1));
+ (n >> sh) & MASK
+}
+
+fn find_mut<'r, T>(child: &'r mut 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(box ref mut x) => {
+ return insert(&mut x.count, &mut x.children[chunk(key, idx)], key, value, idx + 1);
+ }
+ External(stored_key, ref mut stored_value) if stored_key == key => {
+ // swap in the new value and return the old.
+ 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 = box TrieNode::new();
+
+ let ret = {
+ let new_interior = &mut *new;
+ insert(&mut new_interior.count,
+ &mut new_interior.children[chunk(stored_key, idx)],
+ stored_key, stored_value, idx + 1);
+ insert(&mut new_interior.count,
+ &mut new_interior.children[chunk(key, idx)],
+ key, value, idx + 1)
+ };
+
+ *child = Internal(new);
+ return ret;
+ }
+ _ => panic!("unreachable code"),
+ }
+}
+
+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),
+ _ => panic!()
+ }
+ }
+ External(..) => (None, false),
+ Internal(box ref mut x) => {
+ let ret = remove(&mut x.count, &mut x.children[chunk(key, idx)],
+ key, idx + 1);
+ (ret, x.count == 0)
+ }
+ Nothing => (None, false)
+ };
+
+ if this {
+ *child = Nothing;
+ *count -= 1;
+ }
+ return ret;
+}
+
+/// A forward iterator over a map.
+pub struct Entries<'a, T:'a> {
+ stack: [slice::Items<'a, Child<T>>, .. NUM_CHUNKS],
+ length: uint,
+ remaining_min: uint,
+ remaining_max: uint
+}
+
+/// A forward iterator over the key-value pairs of a map, with the
+/// values being mutable.
+pub struct MutEntries<'a, T:'a> {
+ stack: [slice::MutItems<'a, Child<T>>, .. NUM_CHUNKS],
+ length: uint,
+ remaining_min: uint,
+ remaining_max: uint
+}
+
+/// A forward iterator over the keys of a map.
+pub type Keys<'a, T> =
+ iter::Map<'static, (uint, &'a T), uint, Entries<'a, T>>;
+
+/// A forward iterator over the values of a map.
+pub type Values<'a, T> =
+ iter::Map<'static, (uint, &'a T), &'a T, Entries<'a, T>>;
+
+// FIXME #5846: see `addr!` above.
+macro_rules! item { ($i:item) => {$i}}
+
+macro_rules! iterator_impl {
+ ($name:ident,
+ iter = $iter:ident,
+ mutability = $($mut_:tt)*) => {
+ impl<'a, T> $name<'a, T> {
+ // Create new zero'd iterator. We have a thin gilding of safety by
+ // using init rather than uninit, so that the worst that can happen
+ // from failing to initialise correctly after calling these is a
+ // segfault.
+ #[cfg(target_word_size="32")]
+ unsafe fn new() -> $name<'a, T> {
+ $name {
+ remaining_min: 0,
+ remaining_max: 0,
+ length: 0,
+ // ick :( ... at least the compiler will tell us if we screwed up.
+ stack: [zeroed(), zeroed(), zeroed(), zeroed(), zeroed(),
+ zeroed(), zeroed(), zeroed()]
+ }
+ }
+
+ #[cfg(target_word_size="64")]
+ unsafe fn new() -> $name<'a, T> {
+ $name {
+ remaining_min: 0,
+ remaining_max: 0,
+ length: 0,
+ stack: [zeroed(), zeroed(), zeroed(), zeroed(),
+ zeroed(), zeroed(), zeroed(), zeroed(),
+ zeroed(), zeroed(), zeroed(), zeroed(),
+ zeroed(), zeroed(), zeroed(), zeroed()]
+ }
+ }
+ }
+
+ item!(impl<'a, T> Iterator<(uint, &'a $($mut_)* T)> for $name<'a, T> {
+ // you might wonder why we're not even trying to act within the
+ // rules, and are just manipulating raw pointers like there's no
+ // such thing as invalid pointers and memory unsafety. The
+ // reason is performance, without doing this we can get the
+ // (now replaced) bench_iter_large microbenchmark down to about
+ // 30000 ns/iter (using .unsafe_get to index self.stack directly, 38000
+ // ns/iter with [] checked indexing), but this smashes that down
+ // to 13500 ns/iter.
+ //
+ // Fortunately, it's still safe...
+ //
+ // We have an invariant that every Internal node
+ // corresponds to one push to self.stack, and one pop,
+ // nested appropriately. self.stack has enough storage
+ // to store the maximum depth of Internal nodes in the
+ // trie (8 on 32-bit platforms, 16 on 64-bit).
+ fn next(&mut self) -> Option<(uint, &'a $($mut_)* T)> {
+ let start_ptr = self.stack.as_mut_ptr();
+
+ unsafe {
+ // write_ptr is the next place to write to the stack.
+ // invariant: start_ptr <= write_ptr < end of the
+ // vector.
+ let mut write_ptr = start_ptr.offset(self.length as int);
+ while write_ptr != start_ptr {
+ // indexing back one is safe, since write_ptr >
+ // start_ptr now.
+ match (*write_ptr.offset(-1)).next() {
+ // exhausted this iterator (i.e. finished this
+ // Internal node), so pop from the stack.
+ //
+ // don't bother clearing the memory, because the
+ // next time we use it we'll've written to it
+ // first.
+ None => write_ptr = write_ptr.offset(-1),
+ Some(child) => {
+ addr!(match *child {
+ Internal(ref $($mut_)* node) => {
+ // going down a level, so push
+ // to the stack (this is the
+ // write referenced above)
+ *write_ptr = node.children.$iter();
+ write_ptr = write_ptr.offset(1);
+ }
+ External(key, ref $($mut_)* value) => {
+ self.remaining_max -= 1;
+ if self.remaining_min > 0 {
+ self.remaining_min -= 1;
+ }
+ // store the new length of the
+ // stack, based on our current
+ // position.
+ self.length = (write_ptr as uint
+ - start_ptr as uint) /
+ mem::size_of_val(&*write_ptr);
+
+ return Some((key, value));
+ }
+ Nothing => {}
+ })
+ }
+ }
+ }
+ }
+ return None;
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ (self.remaining_min, Some(self.remaining_max))
+ }
+ })
+ }
+}
+
+iterator_impl! { Entries, iter = iter, mutability = }
+iterator_impl! { MutEntries, iter = iter_mut, mutability = mut }
+
+#[cfg(test)]
+mod test {
+ use std::prelude::*;
+ use std::iter::range_step;
+ use std::uint;
+ use std::hash;
+
+ use super::{TrieMap, TrieNode, Internal, External, Nothing};
+
+ 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(1u, 12i));
+ assert!(m.insert(2u, 8i));
+ assert!(m.insert(5u, 14i));
+ let new = 100;
+ match m.find_mut(&5) {
+ None => panic!(), 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(1u, 12i));
+ 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(1u, 2i), None);
+ assert_eq!(m.swap(1u, 3i), Some(2));
+ assert_eq!(m.swap(1u, 4i), Some(3));
+ }
+
+ #[test]
+ fn test_pop() {
+ let mut m = TrieMap::new();
+ m.insert(1u, 2i);
+ assert_eq!(m.pop(&1), Some(2));
+ assert_eq!(m.pop(&1), None);
+ }
+
+ #[test]
+ fn test_from_iter() {
+ let xs = vec![(1u, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+ let map: TrieMap<int> = xs.iter().map(|&x| x).collect();
+
+ for &(k, v) in xs.iter() {
+ assert_eq!(map.find(&k), Some(&v));
+ }
+ }
+
+ #[test]
+ fn test_keys() {
+ let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
+ let map = vec.into_iter().collect::<TrieMap<char>>();
+ let keys = map.keys().collect::<Vec<uint>>();
+ assert_eq!(keys.len(), 3);
+ assert!(keys.contains(&1));
+ assert!(keys.contains(&2));
+ assert!(keys.contains(&3));
+ }
+
+ #[test]
+ fn test_values() {
+ let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
+ let map = vec.into_iter().collect::<TrieMap<char>>();
+ let values = map.values().map(|&v| v).collect::<Vec<char>>();
+ assert_eq!(values.len(), 3);
+ assert!(values.contains(&'a'));
+ assert!(values.contains(&'b'));
+ assert!(values.contains(&'c'));
+ }
+
+ #[test]
+ fn test_iteration() {
+ let empty_map : TrieMap<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.iter_mut().next().is_none());
+
+ let first = uint::MAX - 10000;
+ let last = uint::MAX;
+
+ let mut map = TrieMap::new();
+ for x in range(first, last).rev() {
+ map.insert(x, x / 2);
+ }
+
+ let mut i = 0;
+ for (k, v) in map.iter_mut() {
+ assert_eq!(k, first + i);
+ *v -= k / 2;
+ i += 1;
+ }
+ assert_eq!(i, last - first);
+
+ assert!(map.iter().all(|(_, &v)| v == 0));
+ }
+
+ #[test]
+ fn test_bound() {
+ let empty_map : TrieMap<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.lower_bound_mut(i);
+ let (k, v) = lb_it.next().unwrap();
+ let lb = i + i % 2;
+ assert_eq!(lb, k);
+ *v -= k;
+ }
+
+ for i in range(0u, 198) {
+ let mut ub_it = m_upper.upper_bound_mut(i);
+ let (k, v) = ub_it.next().unwrap();
+ let ub = i + 2 - i % 2;
+ assert_eq!(ub, k);
+ *v -= k;
+ }
+
+ assert!(m_lower.lower_bound_mut(199).next().is_none());
+ assert!(m_upper.upper_bound_mut(198).next().is_none());
+
+ assert!(m_lower.iter().all(|(_, &x)| x == 0));
+ assert!(m_upper.iter().all(|(_, &x)| x == 0));
+ }
+
+ #[test]
+ fn test_clone() {
+ let mut a = TrieMap::new();
+
+ a.insert(1, 'a');
+ a.insert(2, 'b');
+ a.insert(3, 'c');
+
+ assert!(a.clone() == a);
+ }
+
+ #[test]
+ fn test_eq() {
+ let mut a = TrieMap::new();
+ let mut b = TrieMap::new();
+
+ assert!(a == b);
+ assert!(a.insert(0, 5i));
+ assert!(a != b);
+ assert!(b.insert(0, 4i));
+ assert!(a != b);
+ assert!(a.insert(5, 19));
+ assert!(a != b);
+ assert!(!b.insert(0, 5));
+ assert!(a != b);
+ assert!(b.insert(5, 19));
+ assert!(a == b);
+ }
+
+ #[test]
+ fn test_lt() {
+ let mut a = TrieMap::new();
+ let mut b = TrieMap::new();
+
+ assert!(!(a < b) && !(b < a));
+ assert!(b.insert(2u, 5i));
+ assert!(a < b);
+ assert!(a.insert(2, 7));
+ assert!(!(a < b) && b < a);
+ assert!(b.insert(1, 0));
+ assert!(b < a);
+ assert!(a.insert(0, 6));
+ assert!(a < b);
+ assert!(a.insert(6, 2));
+ assert!(a < b && !(b < a));
+ }
+
+ #[test]
+ fn test_ord() {
+ let mut a = TrieMap::new();
+ let mut b = TrieMap::new();
+
+ assert!(a <= b && a >= b);
+ assert!(a.insert(1u, 1i));
+ assert!(a > b && a >= b);
+ assert!(b < a && b <= a);
+ assert!(b.insert(2, 2));
+ assert!(b > a && b >= a);
+ assert!(a < b && a <= b);
+ }
+
+ #[test]
+ fn test_hash() {
+ let mut x = TrieMap::new();
+ let mut y = TrieMap::new();
+
+ assert!(hash::hash(&x) == hash::hash(&y));
+ x.insert(1, 'a');
+ x.insert(2, 'b');
+ x.insert(3, 'c');
+
+ y.insert(3, 'c');
+ y.insert(2, 'b');
+ y.insert(1, 'a');
+
+ assert!(hash::hash(&x) == hash::hash(&y));
+ }
+
+ #[test]
+ fn test_show() {
+ let mut map = TrieMap::new();
+ let empty: TrieMap<uint> = TrieMap::new();
+
+ map.insert(1, 'a');
+ map.insert(2, 'b');
+
+ let map_str = format!("{}", map);
+
+ assert!(map_str == "{1: a, 2: b}".to_string());
+ assert_eq!(format!("{}", empty), "{}".to_string());
+ }
+
+ #[test]
+ fn test_index() {
+ let mut map = TrieMap::new();
+
+ map.insert(1, 2i);
+ map.insert(2, 1i);
+ map.insert(3, 4i);
+
+ assert_eq!(map[2], 1);
+ }
+
+ #[test]
+ #[should_fail]
+ fn test_index_nonexistent() {
+ let mut map = TrieMap::new();
+
+ map.insert(1, 2i);
+ map.insert(2, 1i);
+ map.insert(3, 4i);
+
+ map[4];
+ }
+}
+
+#[cfg(test)]
+mod bench {
+ use std::prelude::*;
+ use std::rand::{weak_rng, Rng};
+ use test::{Bencher, black_box};
+
+ use super::TrieMap;
+
+ fn bench_iter(b: &mut Bencher, size: uint) {
+ let mut map = TrieMap::<uint>::new();
+ let mut rng = weak_rng();
+
+ for _ in range(0, size) {
+ map.swap(rng.gen(), rng.gen());
+ }
+
+ b.iter(|| {
+ for entry in map.iter() {
+ black_box(entry);
+ }
+ });
+ }
+
+ #[bench]
+ pub fn iter_20(b: &mut Bencher) {
+ bench_iter(b, 20);
+ }
+
+ #[bench]
+ pub fn iter_1000(b: &mut Bencher) {
+ bench_iter(b, 1000);
+ }
+
+ #[bench]
+ pub fn iter_100000(b: &mut Bencher) {
+ bench_iter(b, 100000);
+ }
+
+ #[bench]
+ fn bench_lower_bound(b: &mut Bencher) {
+ let mut m = TrieMap::<uint>::new();
+ let mut rng = weak_rng();
+ for _ in range(0u, 1000) {
+ m.insert(rng.gen(), rng.gen());
+ }
+
+ b.iter(|| {
+ for _ in range(0u, 10) {
+ m.lower_bound(rng.gen());
+ }
+ });
+ }
+
+ #[bench]
+ fn bench_upper_bound(b: &mut Bencher) {
+ let mut m = TrieMap::<uint>::new();
+ let mut rng = weak_rng();
+ for _ in range(0u, 1000) {
+ m.insert(rng.gen(), rng.gen());
+ }
+
+ b.iter(|| {
+ for _ in range(0u, 10) {
+ m.upper_bound(rng.gen());
+ }
+ });
+ }
+
+ #[bench]
+ fn bench_insert_large(b: &mut Bencher) {
+ let mut m = TrieMap::<[uint, .. 10]>::new();
+ let mut rng = weak_rng();
+
+ b.iter(|| {
+ for _ in range(0u, 1000) {
+ m.insert(rng.gen(), [1, .. 10]);
+ }
+ })
+ }
+ #[bench]
+ fn bench_insert_large_low_bits(b: &mut Bencher) {
+ let mut m = TrieMap::<[uint, .. 10]>::new();
+ let mut rng = weak_rng();
+
+ b.iter(|| {
+ for _ in range(0u, 1000) {
+ // only have the last few bits set.
+ m.insert(rng.gen::<uint>() & 0xff_ff, [1, .. 10]);
+ }
+ })
+ }
+
+ #[bench]
+ fn bench_insert_small(b: &mut Bencher) {
+ let mut m = TrieMap::<()>::new();
+ let mut rng = weak_rng();
+
+ b.iter(|| {
+ for _ in range(0u, 1000) {
+ m.insert(rng.gen(), ());
+ }
+ })
+ }
+ #[bench]
+ fn bench_insert_small_low_bits(b: &mut Bencher) {
+ let mut m = TrieMap::<()>::new();
+ let mut rng = weak_rng();
+
+ b.iter(|| {
+ for _ in range(0u, 1000) {
+ // only have the last few bits set.
+ m.insert(rng.gen::<uint>() & 0xff_ff, ());
+ }
+ })
+ }
+}
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+//! Maps are collections of unique keys with corresponding values, and sets are
+//! just unique keys without a corresponding value. The `Map` and `Set` traits in
+//! `std::container` define the basic interface.
+//!
+//! This crate defines `TrieMap` and `TrieSet`, which require `uint` keys.
+//!
+//! `TrieMap` is ordered.
+
+pub mod map;
+pub mod set;
\ No newline at end of file
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+use core::prelude::*;
+
+use core::default::Default;
+use core::fmt;
+use core::fmt::Show;
+use std::hash::Hash;
+
+use trie_map::{TrieMap, Entries};
+
+/// A set implemented as a radix trie.
+///
+/// # Example
+///
+/// ```
+/// use std::collections::TrieSet;
+///
+/// let mut set = TrieSet::new();
+/// set.insert(6);
+/// set.insert(28);
+/// set.insert(6);
+///
+/// assert_eq!(set.len(), 2);
+///
+/// if !set.contains(&3) {
+/// println!("3 is not in the set");
+/// }
+///
+/// // Print contents in order
+/// for x in set.iter() {
+/// println!("{}", x);
+/// }
+///
+/// set.remove(&6);
+/// assert_eq!(set.len(), 1);
+///
+/// set.clear();
+/// assert!(set.is_empty());
+/// ```
+#[deriving(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
+pub struct TrieSet {
+ map: TrieMap<()>
+}
+
+impl Show for TrieSet {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ try!(write!(f, "{{"));
+
+ for (i, x) in self.iter().enumerate() {
+ if i != 0 { try!(write!(f, ", ")); }
+ try!(write!(f, "{}", x));
+ }
+
+ write!(f, "}}")
+ }
+}
+
+impl Default for TrieSet {
+ #[inline]
+ fn default() -> TrieSet { TrieSet::new() }
+}
+
+impl TrieSet {
+ /// Creates an empty TrieSet.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieSet;
+ /// let mut set = TrieSet::new();
+ /// ```
+ #[inline]
+ pub fn new() -> TrieSet {
+ TrieSet{map: TrieMap::new()}
+ }
+
+ /// Visits all values in reverse order. Aborts traversal when `f` returns `false`.
+ /// Returns `true` if `f` returns `true` for all elements.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieSet;
+ ///
+ /// let set: TrieSet = [1, 2, 3, 4, 5].iter().map(|&x| x).collect();
+ ///
+ /// let mut vec = Vec::new();
+ /// assert_eq!(true, set.each_reverse(|&x| { vec.push(x); true }));
+ /// assert_eq!(vec, vec![5, 4, 3, 2, 1]);
+ ///
+ /// // Stop when we reach 3
+ /// let mut vec = Vec::new();
+ /// assert_eq!(false, set.each_reverse(|&x| { vec.push(x); x != 3 }));
+ /// assert_eq!(vec, vec![5, 4, 3]);
+ /// ```
+ #[inline]
+ pub fn each_reverse(&self, f: |&uint| -> bool) -> bool {
+ self.map.each_reverse(|k, _| f(k))
+ }
+
+ /// Gets an iterator over the values in the set, in sorted order.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieSet;
+ ///
+ /// let mut set = TrieSet::new();
+ /// set.insert(3);
+ /// set.insert(2);
+ /// set.insert(1);
+ /// set.insert(2);
+ ///
+ /// // Print 1, 2, 3
+ /// for x in set.iter() {
+ /// println!("{}", x);
+ /// }
+ /// ```
+ #[inline]
+ pub fn iter<'a>(&'a self) -> SetItems<'a> {
+ SetItems{iter: self.map.iter()}
+ }
+
+ /// Gets an iterator pointing to the first value that is not less than `val`.
+ /// If all values in the set are less than `val` an empty iterator is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieSet;
+ ///
+ /// let set: TrieSet = [2, 4, 6, 8].iter().map(|&x| x).collect();
+ /// assert_eq!(set.lower_bound(4).next(), Some(4));
+ /// assert_eq!(set.lower_bound(5).next(), Some(6));
+ /// assert_eq!(set.lower_bound(10).next(), None);
+ /// ```
+ pub fn lower_bound<'a>(&'a self, val: uint) -> SetItems<'a> {
+ SetItems{iter: self.map.lower_bound(val)}
+ }
+
+ /// Gets an iterator pointing to the first value that key is greater than `val`.
+ /// If all values in the set are less than or equal to `val` an empty iterator is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieSet;
+ ///
+ /// let set: TrieSet = [2, 4, 6, 8].iter().map(|&x| x).collect();
+ /// assert_eq!(set.upper_bound(4).next(), Some(6));
+ /// assert_eq!(set.upper_bound(5).next(), Some(6));
+ /// assert_eq!(set.upper_bound(10).next(), None);
+ /// ```
+ pub fn upper_bound<'a>(&'a self, val: uint) -> SetItems<'a> {
+ SetItems{iter: self.map.upper_bound(val)}
+ }
+
+ /// Return the number of elements in the set
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieSet;
+ ///
+ /// let mut v = TrieSet::new();
+ /// assert_eq!(v.len(), 0);
+ /// v.insert(1);
+ /// assert_eq!(v.len(), 1);
+ /// ```
+ #[inline]
+ pub fn len(&self) -> uint { self.map.len() }
+
+ /// Returns true if the set contains no elements
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieSet;
+ ///
+ /// let mut v = TrieSet::new();
+ /// assert!(v.is_empty());
+ /// v.insert(1);
+ /// assert!(!v.is_empty());
+ /// ```
+ pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+ /// Clears the set, removing all values.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieSet;
+ ///
+ /// let mut v = TrieSet::new();
+ /// v.insert(1);
+ /// v.clear();
+ /// assert!(v.is_empty());
+ /// ```
+ #[inline]
+ pub fn clear(&mut self) { self.map.clear() }
+
+ /// Returns `true` if the set contains a value.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieSet;
+ ///
+ /// let set: TrieSet = [1, 2, 3].iter().map(|&x| x).collect();
+ /// assert_eq!(set.contains(&1), true);
+ /// assert_eq!(set.contains(&4), false);
+ /// ```
+ #[inline]
+ pub fn contains(&self, value: &uint) -> bool {
+ self.map.contains_key(value)
+ }
+
+ /// Returns `true` if the set has no elements in common with `other`.
+ /// This is equivalent to checking for an empty intersection.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieSet;
+ ///
+ /// let a: TrieSet = [1, 2, 3].iter().map(|&x| x).collect();
+ /// let mut b: TrieSet = TrieSet::new();
+ ///
+ /// assert_eq!(a.is_disjoint(&b), true);
+ /// b.insert(4);
+ /// assert_eq!(a.is_disjoint(&b), true);
+ /// b.insert(1);
+ /// assert_eq!(a.is_disjoint(&b), false);
+ /// ```
+ #[inline]
+ pub fn is_disjoint(&self, other: &TrieSet) -> bool {
+ self.iter().all(|v| !other.contains(&v))
+ }
+
+ /// Returns `true` if the set is a subset of another.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieSet;
+ ///
+ /// let sup: TrieSet = [1, 2, 3].iter().map(|&x| x).collect();
+ /// let mut set: TrieSet = TrieSet::new();
+ ///
+ /// assert_eq!(set.is_subset(&sup), true);
+ /// set.insert(2);
+ /// assert_eq!(set.is_subset(&sup), true);
+ /// set.insert(4);
+ /// assert_eq!(set.is_subset(&sup), false);
+ /// ```
+ #[inline]
+ pub fn is_subset(&self, other: &TrieSet) -> bool {
+ self.iter().all(|v| other.contains(&v))
+ }
+
+ /// Returns `true` if the set is a superset of another.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieSet;
+ ///
+ /// let sub: TrieSet = [1, 2].iter().map(|&x| x).collect();
+ /// let mut set: TrieSet = TrieSet::new();
+ ///
+ /// assert_eq!(set.is_superset(&sub), false);
+ ///
+ /// set.insert(0);
+ /// set.insert(1);
+ /// assert_eq!(set.is_superset(&sub), false);
+ ///
+ /// set.insert(2);
+ /// assert_eq!(set.is_superset(&sub), true);
+ /// ```
+ #[inline]
+ pub fn is_superset(&self, other: &TrieSet) -> bool {
+ other.is_subset(self)
+ }
+
+ /// Adds a value to the set. Returns `true` if the value was not already
+ /// present in the set.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieSet;
+ ///
+ /// let mut set = TrieSet::new();
+ ///
+ /// assert_eq!(set.insert(2), true);
+ /// assert_eq!(set.insert(2), false);
+ /// assert_eq!(set.len(), 1);
+ /// ```
+ #[inline]
+ pub fn insert(&mut self, value: uint) -> bool {
+ self.map.insert(value, ())
+ }
+
+ /// Removes a value from the set. Returns `true` if the value was
+ /// present in the set.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::TrieSet;
+ ///
+ /// let mut set = TrieSet::new();
+ ///
+ /// set.insert(2);
+ /// assert_eq!(set.remove(&2), true);
+ /// assert_eq!(set.remove(&2), false);
+ /// ```
+ #[inline]
+ pub fn remove(&mut self, value: &uint) -> bool {
+ self.map.remove(value)
+ }
+}
+
+impl FromIterator<uint> for TrieSet {
+ fn from_iter<Iter: Iterator<uint>>(iter: Iter) -> TrieSet {
+ let mut set = TrieSet::new();
+ set.extend(iter);
+ set
+ }
+}
+
+impl Extendable<uint> for TrieSet {
+ fn extend<Iter: Iterator<uint>>(&mut self, mut iter: Iter) {
+ for elem in iter {
+ self.insert(elem);
+ }
+ }
+}
+
+/// A forward iterator over a set.
+pub struct SetItems<'a> {
+ 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)]
+mod test {
+ use std::prelude::*;
+ use std::uint;
+
+ use super::TrieSet;
+
+ #[test]
+ fn test_sane_chunk() {
+ let x = 1;
+ let y = 1 << (uint::BITS - 1);
+
+ let mut trie = TrieSet::new();
+
+ assert!(trie.insert(x));
+ assert!(trie.insert(y));
+
+ assert_eq!(trie.len(), 2);
+
+ let expected = [x, y];
+
+ for (i, x) in trie.iter().enumerate() {
+ assert_eq!(expected[i], x);
+ }
+ }
+
+ #[test]
+ fn test_from_iter() {
+ let xs = vec![9u, 8, 7, 6, 5, 4, 3, 2, 1];
+
+ let set: TrieSet = xs.iter().map(|&x| x).collect();
+
+ for x in xs.iter() {
+ assert!(set.contains(x));
+ }
+ }
+
+ #[test]
+ fn test_show() {
+ let mut set = TrieSet::new();
+ let empty = TrieSet::new();
+
+ set.insert(1);
+ set.insert(2);
+
+ let set_str = format!("{}", set);
+
+ assert!(set_str == "{1, 2}".to_string());
+ assert_eq!(format!("{}", empty), "{}".to_string());
+ }
+
+ #[test]
+ fn test_clone() {
+ let mut a = TrieSet::new();
+
+ a.insert(1);
+ a.insert(2);
+ a.insert(3);
+
+ assert!(a.clone() == a);
+ }
+
+ #[test]
+ fn test_lt() {
+ let mut a = TrieSet::new();
+ let mut b = TrieSet::new();
+
+ assert!(!(a < b) && !(b < a));
+ assert!(b.insert(2u));
+ assert!(a < b);
+ assert!(a.insert(3u));
+ assert!(!(a < b) && b < a);
+ assert!(b.insert(1));
+ assert!(b < a);
+ assert!(a.insert(0));
+ assert!(a < b);
+ assert!(a.insert(6));
+ assert!(a < b && !(b < a));
+ }
+
+ #[test]
+ fn test_ord() {
+ let mut a = TrieSet::new();
+ let mut b = TrieSet::new();
+
+ assert!(a <= b && a >= b);
+ assert!(a.insert(1u));
+ assert!(a > b && a >= b);
+ assert!(b < a && b <= a);
+ assert!(b.insert(2u));
+ assert!(b > a && b >= a);
+ assert!(a < b && a <= b);
+ }
+}
--- /dev/null
+// Copyright 2012-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.
+
+//! A simple map based on a vector for small integer keys. Space requirements
+//! are O(highest integer key).
+
+#![allow(missing_docs)]
+
+use core::prelude::*;
+
+use core::default::Default;
+use core::fmt;
+use core::iter;
+use core::iter::{Enumerate, FilterMap};
+use core::mem::replace;
+
+use {vec, slice};
+use vec::Vec;
+use hash;
+use hash::Hash;
+
+/// A map optimized for small integer keys.
+///
+/// # Example
+///
+/// ```
+/// use std::collections::VecMap;
+///
+/// let mut months = VecMap::new();
+/// months.insert(1, "Jan");
+/// months.insert(2, "Feb");
+/// months.insert(3, "Mar");
+///
+/// if !months.contains_key(&12) {
+/// println!("The end is near!");
+/// }
+///
+/// assert_eq!(months.find(&1), Some(&"Jan"));
+///
+/// match months.find_mut(&3) {
+/// Some(value) => *value = "Venus",
+/// None => (),
+/// }
+///
+/// assert_eq!(months.find(&3), Some(&"Venus"));
+///
+/// // Print out all months
+/// for (key, value) in months.iter() {
+/// println!("month {} is {}", key, value);
+/// }
+///
+/// months.clear();
+/// assert!(months.is_empty());
+/// ```
+#[deriving(PartialEq, Eq)]
+pub struct VecMap<T> {
+ v: Vec<Option<T>>,
+}
+
+impl<V> Default for VecMap<V> {
+ #[inline]
+ fn default() -> VecMap<V> { VecMap::new() }
+}
+
+impl<V:Clone> Clone for VecMap<V> {
+ #[inline]
+ fn clone(&self) -> VecMap<V> {
+ VecMap { v: self.v.clone() }
+ }
+
+ #[inline]
+ fn clone_from(&mut self, source: &VecMap<V>) {
+ self.v.reserve(source.v.len());
+ for (i, w) in self.v.iter_mut().enumerate() {
+ *w = source.v[i].clone();
+ }
+ }
+}
+
+impl <S: hash::Writer, T: Hash<S>> Hash<S> for VecMap<T> {
+ fn hash(&self, state: &mut S) {
+ self.v.hash(state)
+ }
+}
+
+impl<V> VecMap<V> {
+ /// Creates an empty `VecMap`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::VecMap;
+ /// let mut map: VecMap<&str> = VecMap::new();
+ /// ```
+ pub fn new() -> VecMap<V> { VecMap{v: vec!()} }
+
+ /// Creates an empty `VecMap` with space for at least `capacity`
+ /// elements before resizing.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::VecMap;
+ /// let mut map: VecMap<&str> = VecMap::with_capacity(10);
+ /// ```
+ pub fn with_capacity(capacity: uint) -> VecMap<V> {
+ VecMap { v: Vec::with_capacity(capacity) }
+ }
+
+ /// Returns an iterator visiting all keys in ascending order by the keys.
+ /// The iterator's element type is `uint`.
+ pub fn keys<'r>(&'r self) -> Keys<'r, V> {
+ self.iter().map(|(k, _v)| k)
+ }
+
+ /// Returns an iterator visiting all values in ascending order by the keys.
+ /// The iterator's element type is `&'r V`.
+ pub fn values<'r>(&'r self) -> Values<'r, V> {
+ self.iter().map(|(_k, v)| v)
+ }
+
+ /// Returns an iterator visiting all key-value pairs in ascending order by the keys.
+ /// The iterator's element type is `(uint, &'r V)`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::VecMap;
+ ///
+ /// let mut map = VecMap::new();
+ /// map.insert(1, "a");
+ /// map.insert(3, "c");
+ /// map.insert(2, "b");
+ ///
+ /// // Print `1: a` then `2: b` then `3: c`
+ /// for (key, value) in map.iter() {
+ /// println!("{}: {}", key, value);
+ /// }
+ /// ```
+ pub fn iter<'r>(&'r self) -> Entries<'r, V> {
+ Entries {
+ front: 0,
+ back: self.v.len(),
+ iter: self.v.iter()
+ }
+ }
+
+ /// Returns an iterator visiting all key-value pairs in ascending order by the keys,
+ /// with mutable references to the values.
+ /// The iterator's element type is `(uint, &'r mut V)`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::VecMap;
+ ///
+ /// let mut map = VecMap::new();
+ /// map.insert(1, "a");
+ /// map.insert(2, "b");
+ /// map.insert(3, "c");
+ ///
+ /// for (key, value) in map.iter_mut() {
+ /// *value = "x";
+ /// }
+ ///
+ /// for (key, value) in map.iter() {
+ /// assert_eq!(value, &"x");
+ /// }
+ /// ```
+ pub fn iter_mut<'r>(&'r mut self) -> MutEntries<'r, V> {
+ MutEntries {
+ front: 0,
+ back: self.v.len(),
+ iter: self.v.iter_mut()
+ }
+ }
+
+ /// Returns an iterator visiting all key-value pairs in ascending order by
+ /// the keys, emptying (but not consuming) the original `VecMap`.
+ /// The iterator's element type is `(uint, &'r V)`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::VecMap;
+ ///
+ /// let mut map = VecMap::new();
+ /// map.insert(1, "a");
+ /// map.insert(3, "c");
+ /// map.insert(2, "b");
+ ///
+ /// // Not possible with .iter()
+ /// let vec: Vec<(uint, &str)> = map.into_iter().collect();
+ ///
+ /// assert_eq!(vec, vec![(1, "a"), (2, "b"), (3, "c")]);
+ /// ```
+ pub fn into_iter(&mut self)
+ -> FilterMap<(uint, Option<V>), (uint, V),
+ Enumerate<vec::MoveItems<Option<V>>>>
+ {
+ let values = replace(&mut self.v, vec!());
+ values.into_iter().enumerate().filter_map(|(i, v)| {
+ v.map(|v| (i, v))
+ })
+ }
+
+ /// Return the number of elements in the map.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::VecMap;
+ ///
+ /// let mut a = VecMap::new();
+ /// assert_eq!(a.len(), 0);
+ /// a.insert(1, "a");
+ /// assert_eq!(a.len(), 1);
+ /// ```
+ pub fn len(&self) -> uint {
+ self.v.iter().filter(|elt| elt.is_some()).count()
+ }
+
+ /// Return true if the map contains no elements.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::VecMap;
+ ///
+ /// let mut a = VecMap::new();
+ /// assert!(a.is_empty());
+ /// a.insert(1, "a");
+ /// assert!(!a.is_empty());
+ /// ```
+ pub fn is_empty(&self) -> bool {
+ self.v.iter().all(|elt| elt.is_none())
+ }
+
+ /// Clears the map, removing all key-value pairs.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::VecMap;
+ ///
+ /// let mut a = VecMap::new();
+ /// a.insert(1, "a");
+ /// a.clear();
+ /// assert!(a.is_empty());
+ /// ```
+ pub fn clear(&mut self) { self.v.clear() }
+
+ /// Returns a reference to the value corresponding to the key.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::VecMap;
+ ///
+ /// let mut map = VecMap::new();
+ /// map.insert(1, "a");
+ /// assert_eq!(map.find(&1), Some(&"a"));
+ /// assert_eq!(map.find(&2), None);
+ /// ```
+ pub fn find<'a>(&'a self, key: &uint) -> Option<&'a V> {
+ if *key < self.v.len() {
+ match self.v[*key] {
+ Some(ref value) => Some(value),
+ None => None
+ }
+ } else {
+ None
+ }
+ }
+
+ /// Returns true if the map contains a value for the specified key.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::VecMap;
+ ///
+ /// let mut map = VecMap::new();
+ /// map.insert(1, "a");
+ /// assert_eq!(map.contains_key(&1), true);
+ /// assert_eq!(map.contains_key(&2), false);
+ /// ```
+ #[inline]
+ pub fn contains_key(&self, key: &uint) -> bool {
+ self.find(key).is_some()
+ }
+
+ /// Returns a mutable reference to the value corresponding to the key.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::VecMap;
+ ///
+ /// let mut map = VecMap::new();
+ /// map.insert(1, "a");
+ /// match map.find_mut(&1) {
+ /// Some(x) => *x = "b",
+ /// None => (),
+ /// }
+ /// assert_eq!(map[1], "b");
+ /// ```
+ pub fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut V> {
+ if *key < self.v.len() {
+ match *(&mut self.v[*key]) {
+ Some(ref mut value) => Some(value),
+ None => None
+ }
+ } else {
+ None
+ }
+ }
+
+ /// Inserts a key-value pair into the map. An existing value for a
+ /// key is replaced by the new value. Returns `true` if the key did
+ /// not already exist in the map.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::VecMap;
+ ///
+ /// let mut map = VecMap::new();
+ /// assert_eq!(map.insert(2, "value"), true);
+ /// assert_eq!(map.insert(2, "value2"), false);
+ /// assert_eq!(map[2], "value2");
+ /// ```
+ pub fn insert(&mut self, key: uint, value: V) -> bool {
+ let exists = self.contains_key(&key);
+ let len = self.v.len();
+ if len <= key {
+ self.v.grow_fn(key - len + 1, |_| None);
+ }
+ self.v[key] = Some(value);
+ !exists
+ }
+
+ /// Removes a key-value pair from the map. Returns `true` if the key
+ /// was present in the map.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::VecMap;
+ ///
+ /// let mut map = VecMap::new();
+ /// assert_eq!(map.remove(&1), false);
+ /// map.insert(1, "a");
+ /// assert_eq!(map.remove(&1), true);
+ /// ```
+ pub fn remove(&mut self, key: &uint) -> bool {
+ self.pop(key).is_some()
+ }
+
+ /// Inserts a key-value pair from the map. If the key already had a value
+ /// present in the map, that value is returned. Otherwise, `None` is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::VecMap;
+ ///
+ /// let mut map = VecMap::new();
+ /// assert_eq!(map.swap(37, "a"), None);
+ /// assert_eq!(map.is_empty(), false);
+ ///
+ /// map.insert(37, "b");
+ /// assert_eq!(map.swap(37, "c"), Some("b"));
+ /// assert_eq!(map[37], "c");
+ /// ```
+ pub fn swap(&mut self, key: uint, value: V) -> Option<V> {
+ match self.find_mut(&key) {
+ Some(loc) => { return Some(replace(loc, value)); }
+ None => ()
+ }
+ self.insert(key, value);
+ return None;
+ }
+
+ /// Removes a key from the map, returning the value at the key if the key
+ /// was previously in the map.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::VecMap;
+ ///
+ /// let mut map = VecMap::new();
+ /// map.insert(1, "a");
+ /// assert_eq!(map.pop(&1), Some("a"));
+ /// assert_eq!(map.pop(&1), None);
+ /// ```
+ pub fn pop(&mut self, key: &uint) -> Option<V> {
+ if *key >= self.v.len() {
+ return None;
+ }
+ self.v[*key].take()
+ }
+}
+
+impl<V:Clone> VecMap<V> {
+ /// Updates a value in the map. If the key already exists in the map,
+ /// modifies the value with `ff` taking `oldval, newval`.
+ /// Otherwise, sets the value to `newval`.
+ /// Returns `true` if the key did not already exist in the map.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::VecMap;
+ ///
+ /// let mut map = VecMap::new();
+ ///
+ /// // Key does not exist, will do a simple insert
+ /// assert!(map.update(1, vec![1i, 2], |mut old, new| { old.extend(new.into_iter()); old }));
+ /// assert_eq!(map[1], vec![1i, 2]);
+ ///
+ /// // Key exists, update the value
+ /// assert!(!map.update(1, vec![3i, 4], |mut old, new| { old.extend(new.into_iter()); old }));
+ /// assert_eq!(map[1], vec![1i, 2, 3, 4]);
+ /// ```
+ pub fn update(&mut self, key: uint, newval: V, ff: |V, V| -> V) -> bool {
+ self.update_with_key(key, newval, |_k, v, v1| ff(v,v1))
+ }
+
+ /// Updates a value in the map. If the key already exists in the map,
+ /// modifies the value with `ff` taking `key, oldval, newval`.
+ /// Otherwise, sets the value to `newval`.
+ /// Returns `true` if the key did not already exist in the map.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::VecMap;
+ ///
+ /// let mut map = VecMap::new();
+ ///
+ /// // Key does not exist, will do a simple insert
+ /// assert!(map.update_with_key(7, 10, |key, old, new| (old + new) % key));
+ /// assert_eq!(map[7], 10);
+ ///
+ /// // Key exists, update the value
+ /// assert!(!map.update_with_key(7, 20, |key, old, new| (old + new) % key));
+ /// assert_eq!(map[7], 2);
+ /// ```
+ pub fn update_with_key(&mut self,
+ key: uint,
+ val: V,
+ ff: |uint, V, V| -> V)
+ -> bool {
+ let new_val = match self.find(&key) {
+ None => val,
+ Some(orig) => ff(key, (*orig).clone(), val)
+ };
+ self.insert(key, new_val)
+ }
+}
+
+impl<V: PartialOrd> PartialOrd for VecMap<V> {
+ #[inline]
+ fn partial_cmp(&self, other: &VecMap<V>) -> Option<Ordering> {
+ iter::order::partial_cmp(self.iter(), other.iter())
+ }
+}
+
+impl<V: Ord> Ord for VecMap<V> {
+ #[inline]
+ fn cmp(&self, other: &VecMap<V>) -> Ordering {
+ iter::order::cmp(self.iter(), other.iter())
+ }
+}
+
+impl<V: fmt::Show> fmt::Show for VecMap<V> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ try!(write!(f, "{{"));
+
+ for (i, (k, v)) in self.iter().enumerate() {
+ if i != 0 { try!(write!(f, ", ")); }
+ try!(write!(f, "{}: {}", k, *v));
+ }
+
+ write!(f, "}}")
+ }
+}
+
+impl<V> FromIterator<(uint, V)> for VecMap<V> {
+ fn from_iter<Iter: Iterator<(uint, V)>>(iter: Iter) -> VecMap<V> {
+ let mut map = VecMap::new();
+ map.extend(iter);
+ map
+ }
+}
+
+impl<V> Extendable<(uint, V)> for VecMap<V> {
+ fn extend<Iter: Iterator<(uint, V)>>(&mut self, mut iter: Iter) {
+ for (k, v) in iter {
+ self.insert(k, v);
+ }
+ }
+}
+
+impl<V> Index<uint, V> for VecMap<V> {
+ #[inline]
+ fn index<'a>(&'a self, i: &uint) -> &'a V {
+ self.find(i).expect("key not present")
+ }
+}
+
+impl<V> IndexMut<uint, V> for VecMap<V> {
+ #[inline]
+ fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut V {
+ self.find_mut(i).expect("key not present")
+ }
+}
+
+macro_rules! iterator {
+ (impl $name:ident -> $elem:ty, $($getter:ident),+) => {
+ impl<'a, T> Iterator<$elem> for $name<'a, T> {
+ #[inline]
+ fn next(&mut self) -> Option<$elem> {
+ while self.front < self.back {
+ match self.iter.next() {
+ Some(elem) => {
+ if elem.is_some() {
+ let index = self.front;
+ self.front += 1;
+ return Some((index, elem $(. $getter ())+));
+ }
+ }
+ _ => ()
+ }
+ self.front += 1;
+ }
+ None
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ (0, Some(self.back - self.front))
+ }
+ }
+ }
+}
+
+macro_rules! double_ended_iterator {
+ (impl $name:ident -> $elem:ty, $($getter:ident),+) => {
+ impl<'a, T> DoubleEndedIterator<$elem> for $name<'a, T> {
+ #[inline]
+ fn next_back(&mut self) -> Option<$elem> {
+ while self.front < self.back {
+ match self.iter.next_back() {
+ Some(elem) => {
+ if elem.is_some() {
+ self.back -= 1;
+ return Some((self.back, elem$(. $getter ())+));
+ }
+ }
+ _ => ()
+ }
+ self.back -= 1;
+ }
+ None
+ }
+ }
+ }
+}
+
+/// Forward iterator over a map.
+pub struct Entries<'a, T:'a> {
+ front: uint,
+ back: uint,
+ iter: slice::Items<'a, Option<T>>
+}
+
+iterator!(impl Entries -> (uint, &'a T), as_ref, unwrap)
+double_ended_iterator!(impl Entries -> (uint, &'a T), as_ref, unwrap)
+
+/// Forward iterator over the key-value pairs of a map, with the
+/// values being mutable.
+pub struct MutEntries<'a, T:'a> {
+ front: uint,
+ back: uint,
+ iter: slice::MutItems<'a, Option<T>>
+}
+
+iterator!(impl MutEntries -> (uint, &'a mut T), as_mut, unwrap)
+double_ended_iterator!(impl MutEntries -> (uint, &'a mut T), as_mut, unwrap)
+
+/// Forward iterator over the keys of a map
+pub type Keys<'a, T> =
+ iter::Map<'static, (uint, &'a T), uint, Entries<'a, T>>;
+
+/// Forward iterator over the values of a map
+pub type Values<'a, T> =
+ iter::Map<'static, (uint, &'a T), &'a T, Entries<'a, T>>;
+
+#[cfg(test)]
+mod test_map {
+ use std::prelude::*;
+ use vec::Vec;
+ use hash;
+
+ use super::VecMap;
+
+ #[test]
+ fn test_find_mut() {
+ let mut m = VecMap::new();
+ assert!(m.insert(1, 12i));
+ assert!(m.insert(2, 8));
+ assert!(m.insert(5, 14));
+ let new = 100;
+ match m.find_mut(&5) {
+ None => panic!(), Some(x) => *x = new
+ }
+ assert_eq!(m.find(&5), Some(&new));
+ }
+
+ #[test]
+ fn test_len() {
+ let mut map = VecMap::new();
+ assert_eq!(map.len(), 0);
+ assert!(map.is_empty());
+ assert!(map.insert(5, 20i));
+ assert_eq!(map.len(), 1);
+ assert!(!map.is_empty());
+ assert!(map.insert(11, 12));
+ assert_eq!(map.len(), 2);
+ assert!(!map.is_empty());
+ assert!(map.insert(14, 22));
+ assert_eq!(map.len(), 3);
+ assert!(!map.is_empty());
+ }
+
+ #[test]
+ fn test_clear() {
+ let mut map = VecMap::new();
+ assert!(map.insert(5, 20i));
+ assert!(map.insert(11, 12));
+ assert!(map.insert(14, 22));
+ map.clear();
+ assert!(map.is_empty());
+ assert!(map.find(&5).is_none());
+ assert!(map.find(&11).is_none());
+ assert!(map.find(&14).is_none());
+ }
+
+ #[test]
+ fn test_insert_with_key() {
+ let mut map = VecMap::new();
+
+ // given a new key, initialize it with this new count,
+ // given an existing key, add more to its count
+ fn add_more_to_count(_k: uint, v0: uint, v1: uint) -> uint {
+ v0 + v1
+ }
+
+ fn add_more_to_count_simple(v0: uint, v1: uint) -> uint {
+ v0 + v1
+ }
+
+ // count integers
+ map.update(3, 1, add_more_to_count_simple);
+ map.update_with_key(9, 1, add_more_to_count);
+ map.update(3, 7, add_more_to_count_simple);
+ map.update_with_key(5, 3, add_more_to_count);
+ map.update_with_key(3, 2, add_more_to_count);
+
+ // check the total counts
+ assert_eq!(map.find(&3).unwrap(), &10);
+ assert_eq!(map.find(&5).unwrap(), &3);
+ assert_eq!(map.find(&9).unwrap(), &1);
+
+ // sadly, no sevens were counted
+ assert!(map.find(&7).is_none());
+ }
+
+ #[test]
+ fn test_swap() {
+ let mut m = VecMap::new();
+ assert_eq!(m.swap(1, 2i), None);
+ assert_eq!(m.swap(1, 3i), Some(2));
+ assert_eq!(m.swap(1, 4i), Some(3));
+ }
+
+ #[test]
+ fn test_pop() {
+ let mut m = VecMap::new();
+ m.insert(1, 2i);
+ assert_eq!(m.pop(&1), Some(2));
+ assert_eq!(m.pop(&1), None);
+ }
+
+ #[test]
+ fn test_keys() {
+ let mut map = VecMap::new();
+ map.insert(1, 'a');
+ map.insert(2, 'b');
+ map.insert(3, 'c');
+ let keys = map.keys().collect::<Vec<uint>>();
+ assert_eq!(keys.len(), 3);
+ assert!(keys.contains(&1));
+ assert!(keys.contains(&2));
+ assert!(keys.contains(&3));
+ }
+
+ #[test]
+ fn test_values() {
+ let mut map = VecMap::new();
+ map.insert(1, 'a');
+ map.insert(2, 'b');
+ map.insert(3, 'c');
+ let values = map.values().map(|&v| v).collect::<Vec<char>>();
+ assert_eq!(values.len(), 3);
+ assert!(values.contains(&'a'));
+ assert!(values.contains(&'b'));
+ assert!(values.contains(&'c'));
+ }
+
+ #[test]
+ fn test_iterator() {
+ let mut m = VecMap::new();
+
+ assert!(m.insert(0, 1i));
+ assert!(m.insert(1, 2));
+ assert!(m.insert(3, 5));
+ assert!(m.insert(6, 10));
+ assert!(m.insert(10, 11));
+
+ let mut it = m.iter();
+ assert_eq!(it.size_hint(), (0, Some(11)));
+ assert_eq!(it.next().unwrap(), (0, &1));
+ assert_eq!(it.size_hint(), (0, Some(10)));
+ assert_eq!(it.next().unwrap(), (1, &2));
+ assert_eq!(it.size_hint(), (0, Some(9)));
+ assert_eq!(it.next().unwrap(), (3, &5));
+ assert_eq!(it.size_hint(), (0, Some(7)));
+ assert_eq!(it.next().unwrap(), (6, &10));
+ assert_eq!(it.size_hint(), (0, Some(4)));
+ assert_eq!(it.next().unwrap(), (10, &11));
+ assert_eq!(it.size_hint(), (0, Some(0)));
+ assert!(it.next().is_none());
+ }
+
+ #[test]
+ fn test_iterator_size_hints() {
+ let mut m = VecMap::new();
+
+ assert!(m.insert(0, 1i));
+ assert!(m.insert(1, 2));
+ assert!(m.insert(3, 5));
+ assert!(m.insert(6, 10));
+ assert!(m.insert(10, 11));
+
+ assert_eq!(m.iter().size_hint(), (0, Some(11)));
+ assert_eq!(m.iter().rev().size_hint(), (0, Some(11)));
+ assert_eq!(m.iter_mut().size_hint(), (0, Some(11)));
+ assert_eq!(m.iter_mut().rev().size_hint(), (0, Some(11)));
+ }
+
+ #[test]
+ fn test_mut_iterator() {
+ let mut m = VecMap::new();
+
+ assert!(m.insert(0, 1i));
+ assert!(m.insert(1, 2));
+ assert!(m.insert(3, 5));
+ assert!(m.insert(6, 10));
+ assert!(m.insert(10, 11));
+
+ for (k, v) in m.iter_mut() {
+ *v += k as int;
+ }
+
+ let mut it = m.iter();
+ assert_eq!(it.next().unwrap(), (0, &1));
+ assert_eq!(it.next().unwrap(), (1, &3));
+ assert_eq!(it.next().unwrap(), (3, &8));
+ assert_eq!(it.next().unwrap(), (6, &16));
+ assert_eq!(it.next().unwrap(), (10, &21));
+ assert!(it.next().is_none());
+ }
+
+ #[test]
+ fn test_rev_iterator() {
+ let mut m = VecMap::new();
+
+ assert!(m.insert(0, 1i));
+ assert!(m.insert(1, 2));
+ assert!(m.insert(3, 5));
+ assert!(m.insert(6, 10));
+ assert!(m.insert(10, 11));
+
+ let mut it = m.iter().rev();
+ assert_eq!(it.next().unwrap(), (10, &11));
+ assert_eq!(it.next().unwrap(), (6, &10));
+ assert_eq!(it.next().unwrap(), (3, &5));
+ assert_eq!(it.next().unwrap(), (1, &2));
+ assert_eq!(it.next().unwrap(), (0, &1));
+ assert!(it.next().is_none());
+ }
+
+ #[test]
+ fn test_mut_rev_iterator() {
+ let mut m = VecMap::new();
+
+ assert!(m.insert(0, 1i));
+ assert!(m.insert(1, 2));
+ assert!(m.insert(3, 5));
+ assert!(m.insert(6, 10));
+ assert!(m.insert(10, 11));
+
+ for (k, v) in m.iter_mut().rev() {
+ *v += k as int;
+ }
+
+ let mut it = m.iter();
+ assert_eq!(it.next().unwrap(), (0, &1));
+ assert_eq!(it.next().unwrap(), (1, &3));
+ assert_eq!(it.next().unwrap(), (3, &8));
+ assert_eq!(it.next().unwrap(), (6, &16));
+ assert_eq!(it.next().unwrap(), (10, &21));
+ assert!(it.next().is_none());
+ }
+
+ #[test]
+ fn test_move_iter() {
+ let mut m = VecMap::new();
+ m.insert(1, box 2i);
+ let mut called = false;
+ for (k, v) in m.into_iter() {
+ assert!(!called);
+ called = true;
+ assert_eq!(k, 1);
+ assert_eq!(v, box 2i);
+ }
+ assert!(called);
+ m.insert(2, box 1i);
+ }
+
+ #[test]
+ fn test_show() {
+ let mut map = VecMap::new();
+ let empty = VecMap::<int>::new();
+
+ map.insert(1, 2i);
+ map.insert(3, 4i);
+
+ let map_str = map.to_string();
+ let map_str = map_str.as_slice();
+ assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
+ assert_eq!(format!("{}", empty), "{}".to_string());
+ }
+
+ #[test]
+ fn test_clone() {
+ let mut a = VecMap::new();
+
+ a.insert(1, 'x');
+ a.insert(4, 'y');
+ a.insert(6, 'z');
+
+ assert!(a.clone() == a);
+ }
+
+ #[test]
+ fn test_eq() {
+ let mut a = VecMap::new();
+ let mut b = VecMap::new();
+
+ assert!(a == b);
+ assert!(a.insert(0, 5i));
+ assert!(a != b);
+ assert!(b.insert(0, 4i));
+ assert!(a != b);
+ assert!(a.insert(5, 19));
+ assert!(a != b);
+ assert!(!b.insert(0, 5));
+ assert!(a != b);
+ assert!(b.insert(5, 19));
+ assert!(a == b);
+ }
+
+ #[test]
+ fn test_lt() {
+ let mut a = VecMap::new();
+ let mut b = VecMap::new();
+
+ assert!(!(a < b) && !(b < a));
+ assert!(b.insert(2u, 5i));
+ assert!(a < b);
+ assert!(a.insert(2, 7));
+ assert!(!(a < b) && b < a);
+ assert!(b.insert(1, 0));
+ assert!(b < a);
+ assert!(a.insert(0, 6));
+ assert!(a < b);
+ assert!(a.insert(6, 2));
+ assert!(a < b && !(b < a));
+ }
+
+ #[test]
+ fn test_ord() {
+ let mut a = VecMap::new();
+ let mut b = VecMap::new();
+
+ assert!(a <= b && a >= b);
+ assert!(a.insert(1u, 1i));
+ assert!(a > b && a >= b);
+ assert!(b < a && b <= a);
+ assert!(b.insert(2, 2));
+ assert!(b > a && b >= a);
+ assert!(a < b && a <= b);
+ }
+
+ #[test]
+ fn test_hash() {
+ let mut x = VecMap::new();
+ let mut y = VecMap::new();
+
+ assert!(hash::hash(&x) == hash::hash(&y));
+ x.insert(1, 'a');
+ x.insert(2, 'b');
+ x.insert(3, 'c');
+
+ y.insert(3, 'c');
+ y.insert(2, 'b');
+ y.insert(1, 'a');
+
+ assert!(hash::hash(&x) == hash::hash(&y));
+ }
+
+ #[test]
+ fn test_from_iter() {
+ let xs: Vec<(uint, char)> = vec![(1u, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')];
+
+ let map: VecMap<char> = xs.iter().map(|&x| x).collect();
+
+ for &(k, v) in xs.iter() {
+ assert_eq!(map.find(&k), Some(&v));
+ }
+ }
+
+ #[test]
+ fn test_index() {
+ let mut map: VecMap<int> = VecMap::new();
+
+ map.insert(1, 2);
+ map.insert(2, 1);
+ map.insert(3, 4);
+
+ assert_eq!(map[3], 4);
+ }
+
+ #[test]
+ #[should_fail]
+ fn test_index_nonexistent() {
+ let mut map: VecMap<int> = VecMap::new();
+
+ map.insert(1, 2);
+ map.insert(2, 1);
+ map.insert(3, 4);
+
+ map[4];
+ }
+}
+
+#[cfg(test)]
+mod bench {
+ extern crate test;
+ use self::test::Bencher;
+ use super::VecMap;
+ use bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n};
+
+ #[bench]
+ pub fn insert_rand_100(b: &mut Bencher) {
+ let mut m : VecMap<uint> = VecMap::new();
+ insert_rand_n(100, &mut m, b,
+ |m, i| { m.insert(i, 1); },
+ |m, i| { m.remove(&i); });
+ }
+
+ #[bench]
+ pub fn insert_rand_10_000(b: &mut Bencher) {
+ let mut m : VecMap<uint> = VecMap::new();
+ insert_rand_n(10_000, &mut m, b,
+ |m, i| { m.insert(i, 1); },
+ |m, i| { m.remove(&i); });
+ }
+
+ // Insert seq
+ #[bench]
+ pub fn insert_seq_100(b: &mut Bencher) {
+ let mut m : VecMap<uint> = VecMap::new();
+ insert_seq_n(100, &mut m, b,
+ |m, i| { m.insert(i, 1); },
+ |m, i| { m.remove(&i); });
+ }
+
+ #[bench]
+ pub fn insert_seq_10_000(b: &mut Bencher) {
+ let mut m : VecMap<uint> = VecMap::new();
+ insert_seq_n(10_000, &mut m, b,
+ |m, i| { m.insert(i, 1); },
+ |m, i| { m.remove(&i); });
+ }
+
+ // Find rand
+ #[bench]
+ pub fn find_rand_100(b: &mut Bencher) {
+ let mut m : VecMap<uint> = VecMap::new();
+ find_rand_n(100, &mut m, b,
+ |m, i| { m.insert(i, 1); },
+ |m, i| { m.find(&i); });
+ }
+
+ #[bench]
+ pub fn find_rand_10_000(b: &mut Bencher) {
+ let mut m : VecMap<uint> = VecMap::new();
+ find_rand_n(10_000, &mut m, b,
+ |m, i| { m.insert(i, 1); },
+ |m, i| { m.find(&i); });
+ }
+
+ // Find seq
+ #[bench]
+ pub fn find_seq_100(b: &mut Bencher) {
+ let mut m : VecMap<uint> = VecMap::new();
+ find_seq_n(100, &mut m, b,
+ |m, i| { m.insert(i, 1); },
+ |m, i| { m.find(&i); });
+ }
+
+ #[bench]
+ pub fn find_seq_10_000(b: &mut Bencher) {
+ let mut m : VecMap<uint> = VecMap::new();
+ find_seq_n(10_000, &mut m, b,
+ |m, i| { m.insert(i, 1); },
+ |m, i| { m.find(&i); });
+ }
+}
use syntax::parse::token::InternedString;
use std::collections::HashMap;
-use std::collections::hashmap::{Occupied, Vacant};
+use std::collections::hash_map::{Occupied, Vacant};
use getopts::{optopt, optmulti, optflag, optflagopt};
use getopts;
use std::cell::{RefCell};
use std::cmp;
use std::collections::HashMap;
-use std::collections::hashmap::{Occupied, Vacant};
+use std::collections::hash_map::{Occupied, Vacant};
use std::slice;
use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
use syntax::abi;
use std::rc::Rc;
use std::collections::HashMap;
-use std::collections::hashmap::{Occupied, Vacant};
+use std::collections::hash_map::{Occupied, Vacant};
use syntax::ast;
use syntax::abi;
use syntax::attr;
use syntax::diagnostic::expect;
use syntax::parse::token;
-use std::collections::hashmap::HashMap;
+use std::collections::hash_map::HashMap;
pub struct MethodInfo {
pub name: ast::Name,
use std::hash;
use std::io::extensions::u64_from_be_bytes;
use std::io;
-use std::collections::hashmap::HashMap;
+use std::collections::hash_map::HashMap;
use std::rc::Rc;
use std::u64;
use rbml::reader;
use std::string;
use std::collections::{HashMap, HashSet};
-use std::collections::hashmap::{Occupied, Vacant};
+use std::collections::hash_map::{Occupied, Vacant};
use flate;
use time;
use syntax::{ast, ast_map, ast_util, codemap};
use std::rc::Rc;
-use std::collections::hashmap::Vacant;
+use std::collections::hash_map::Vacant;
//
// This pass classifies expressions by their constant-ness.
use syntax::visit::Visitor;
use std::collections::{HashMap, HashSet};
-use std::collections::hashmap::{Occupied, Vacant};
+use std::collections::hash_map::{Occupied, Vacant};
use std::cell::{Cell, RefCell};
use std::mem::replace;
use std::rc::{Rc, Weak};
use middle::typeck::infer::{InferCtxt, TypeSkolemizer};
use middle::ty_fold::TypeFoldable;
use std::cell::RefCell;
-use std::collections::hashmap::HashMap;
+use std::collections::hash_map::HashMap;
use std::rc::Rc;
use syntax::ast;
use util::ppaux::Repr;
use std::ops;
use std::rc::Rc;
use std::collections::{HashMap, HashSet};
-use std::collections::hashmap::{Occupied, Vacant};
+use std::collections::hash_map::{Occupied, Vacant};
use arena::TypedArena;
use syntax::abi;
use syntax::ast::{CrateNum, DefId, FnStyle, Ident, ItemTrait, LOCAL_CRATE};
use std::cmp;
use std::collections::HashMap;
-use std::collections::hashmap::{Occupied, Vacant};
+use std::collections::hash_map::{Occupied, Vacant};
use syntax::ast;
use syntax::ast_util;
use syntax::codemap::{Span, Spanned};
use std::cell::{Cell, Ref, RefCell};
use std::collections::HashMap;
-use std::collections::hashmap::{Occupied, Vacant};
+use std::collections::hash_map::{Occupied, Vacant};
use std::mem::replace;
use std::rc::Rc;
use syntax::abi;
use std::cell::{RefCell};
use std::collections::HashMap;
-use std::collections::hashmap::{Vacant, Occupied};
+use std::collections::hash_map::{Vacant, Occupied};
///////////////////////////////////////////////////////////////////////////
// PUBLIC ENTRY POINTS
use syntax::ast;
use std::collections::HashMap;
-use std::collections::hashmap::{Occupied, Vacant};
+use std::collections::hash_map::{Occupied, Vacant};
use util::ppaux::Repr;
// Helper functions related to manipulating region types.
use middle::ty_fold;
use middle::ty_fold::TypeFoldable;
use middle::ty_fold::TypeFolder;
-use std::collections::hashmap;
+use std::collections::hash_map;
use super::InferCtxt;
use super::unify::InferCtxtMethodsForSimplyUnifiableTypes;
pub struct TypeSkolemizer<'a, 'tcx:'a> {
infcx: &'a InferCtxt<'a, 'tcx>,
skolemization_count: uint,
- skolemization_map: hashmap::HashMap<ty::InferTy, ty::t>,
+ skolemization_map: hash_map::HashMap<ty::InferTy, ty::t>,
}
impl<'a, 'tcx> TypeSkolemizer<'a, 'tcx> {
TypeSkolemizer {
infcx: infcx,
skolemization_count: 0,
- skolemization_map: hashmap::HashMap::new(),
+ skolemization_map: hash_map::HashMap::new(),
}
}
}
match self.skolemization_map.entry(key) {
- hashmap::Occupied(entry) => *entry.get(),
- hashmap::Vacant(entry) => {
+ hash_map::Occupied(entry) => *entry.get(),
+ hash_map::Vacant(entry) => {
let index = self.skolemization_count;
self.skolemization_count += 1;
let t = ty::mk_infer(self.infcx.tcx, skolemizer(index));
//! both occur before the crate is rendered.
use std::collections::{HashMap, HashSet};
-use std::collections::hashmap::{Occupied, Vacant};
+use std::collections::hash_map::{Occupied, Vacant};
use std::fmt;
use std::io::fs::PathExtensions;
use std::io::{fs, File, BufferedWriter, MemWriter, BufferedReader};
use std::io;
use std::io::{File, MemWriter};
use std::collections::HashMap;
-use std::collections::hashmap::{Occupied, Vacant};
+use std::collections::hash_map::{Occupied, Vacant};
use serialize::{json, Decodable, Encodable};
use externalfiles::ExternalHtml;
use core::prelude::*;
use alloc::heap;
-use collections::treemap::TreeMap;
+use collections::TreeMap;
use core::cmp;
use core::kinds::marker;
use core::mem;
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+#![cfg(test)]
+
+extern crate test;
+use prelude::*;
+
+use self::test::Bencher;
+use iter::{range_inclusive};
+
+#[bench]
+fn new_drop(b : &mut Bencher) {
+ use super::map::HashMap;
+
+ b.iter(|| {
+ let m : HashMap<int, int> = HashMap::new();
+ assert_eq!(m.len(), 0);
+ })
+}
+
+#[bench]
+fn new_insert_drop(b : &mut Bencher) {
+ use super::map::HashMap;
+
+ b.iter(|| {
+ let mut m = HashMap::new();
+ m.insert(0i, 0i);
+ assert_eq!(m.len(), 1);
+ })
+}
+
+#[bench]
+fn grow_by_insertion(b: &mut Bencher) {
+ use super::map::HashMap;
+
+ let mut m = HashMap::new();
+
+ for i in range_inclusive(1i, 1000) {
+ m.insert(i, i);
+ }
+
+ let mut k = 1001;
+
+ b.iter(|| {
+ m.insert(k, k);
+ k += 1;
+ });
+}
+
+#[bench]
+fn find_existing(b: &mut Bencher) {
+ use super::map::HashMap;
+
+ let mut m = HashMap::new();
+
+ for i in range_inclusive(1i, 1000) {
+ m.insert(i, i);
+ }
+
+ b.iter(|| {
+ for i in range_inclusive(1i, 1000) {
+ m.contains_key(&i);
+ }
+ });
+}
+
+#[bench]
+fn find_nonexisting(b: &mut Bencher) {
+ use super::map::HashMap;
+
+ let mut m = HashMap::new();
+
+ for i in range_inclusive(1i, 1000) {
+ m.insert(i, i);
+ }
+
+ b.iter(|| {
+ for i in range_inclusive(1001i, 2000) {
+ m.contains_key(&i);
+ }
+ });
+}
+
+#[bench]
+fn hashmap_as_queue(b: &mut Bencher) {
+ use super::map::HashMap;
+
+ let mut m = HashMap::new();
+
+ for i in range_inclusive(1i, 1000) {
+ m.insert(i, i);
+ }
+
+ let mut k = 1i;
+
+ b.iter(|| {
+ m.pop(&k);
+ m.insert(k + 1000, k + 1000);
+ k += 1;
+ });
+}
+
+#[bench]
+fn find_pop_insert(b: &mut Bencher) {
+ use super::map::HashMap;
+
+ let mut m = HashMap::new();
+
+ for i in range_inclusive(1i, 1000) {
+ m.insert(i, i);
+ }
+
+ let mut k = 1i;
+
+ b.iter(|| {
+ m.find(&(k + 400));
+ m.find(&(k + 2000));
+ m.pop(&k);
+ m.insert(k + 1000, k + 1000);
+ k += 1;
+ })
+}
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+//
+// ignore-lexer-test FIXME #15883
+
+use clone::Clone;
+use cmp::{max, Eq, Equiv, PartialEq};
+use default::Default;
+use fmt::{mod, Show};
+use hash::{Hash, Hasher, RandomSipHasher};
+use iter::{mod, Iterator, FromIterator, Extendable};
+use kinds::Sized;
+use mem::{mod, replace};
+use num;
+use ops::{Deref, Index, IndexMut};
+use option::{Some, None, Option};
+use result::{Result, Ok, Err};
+
+use super::table;
+use super::table::{
+ Bucket,
+ Empty,
+ EmptyBucket,
+ Full,
+ FullBucket,
+ FullBucketImm,
+ FullBucketMut,
+ RawTable,
+ SafeHash
+};
+
+const INITIAL_LOG2_CAP: uint = 5;
+pub const INITIAL_CAPACITY: uint = 1 << INITIAL_LOG2_CAP; // 2^5
+
+/// The default behavior of HashMap implements a load factor of 90.9%.
+/// This behavior is characterized by the following conditions:
+///
+/// - if size > 0.909 * capacity: grow
+/// - if size < 0.25 * capacity: shrink (if this won't bring capacity lower
+/// than the minimum)
+#[deriving(Clone)]
+struct DefaultResizePolicy {
+ /// Doubled minimal capacity. The capacity must never drop below
+ /// the minimum capacity. (The check happens before the capacity
+ /// is potentially halved.)
+ minimum_capacity2: uint
+}
+
+impl DefaultResizePolicy {
+ fn new(new_capacity: uint) -> DefaultResizePolicy {
+ DefaultResizePolicy {
+ minimum_capacity2: new_capacity << 1
+ }
+ }
+
+ #[inline]
+ fn capacity_range(&self, new_size: uint) -> (uint, uint) {
+ // Here, we are rephrasing the logic by specifying the ranges:
+ //
+ // - if `size * 1.1 < cap < size * 4`: don't resize
+ // - if `cap < minimum_capacity * 2`: don't shrink
+ // - otherwise, resize accordingly
+ ((new_size * 11) / 10, max(new_size << 2, self.minimum_capacity2))
+ }
+
+ #[inline]
+ fn reserve(&mut self, new_capacity: uint) {
+ self.minimum_capacity2 = new_capacity << 1;
+ }
+}
+
+// The main performance trick in this hashmap is called Robin Hood Hashing.
+// It gains its excellent performance from one essential operation:
+//
+// If an insertion collides with an existing element, and that element's
+// "probe distance" (how far away the element is from its ideal location)
+// is higher than how far we've already probed, swap the elements.
+//
+// This massively lowers variance in probe distance, and allows us to get very
+// high load factors with good performance. The 90% load factor I use is rather
+// conservative.
+//
+// > Why a load factor of approximately 90%?
+//
+// In general, all the distances to initial buckets will converge on the mean.
+// At a load factor of α, the odds of finding the target bucket after k
+// probes is approximately 1-α^k. If we set this equal to 50% (since we converge
+// on the mean) and set k=8 (64-byte cache line / 8-byte hash), α=0.92. I round
+// this down to make the math easier on the CPU and avoid its FPU.
+// Since on average we start the probing in the middle of a cache line, this
+// strategy pulls in two cache lines of hashes on every lookup. I think that's
+// pretty good, but if you want to trade off some space, it could go down to one
+// cache line on average with an α of 0.84.
+//
+// > Wait, what? Where did you get 1-α^k from?
+//
+// On the first probe, your odds of a collision with an existing element is α.
+// The odds of doing this twice in a row is approximately α^2. For three times,
+// α^3, etc. Therefore, the odds of colliding k times is α^k. The odds of NOT
+// colliding after k tries is 1-α^k.
+//
+// The paper from 1986 cited below mentions an implementation which keeps track
+// of the distance-to-initial-bucket histogram. This approach is not suitable
+// for modern architectures because it requires maintaining an internal data
+// structure. This allows very good first guesses, but we are most concerned
+// with guessing entire cache lines, not individual indexes. Furthermore, array
+// accesses are no longer linear and in one direction, as we have now. There
+// is also memory and cache pressure that this would entail that would be very
+// difficult to properly see in a microbenchmark.
+//
+// ## Future Improvements (FIXME!)
+//
+// Allow the load factor to be changed dynamically and/or at initialization.
+//
+// Also, would it be possible for us to reuse storage when growing the
+// underlying table? This is exactly the use case for 'realloc', and may
+// be worth exploring.
+//
+// ## Future Optimizations (FIXME!)
+//
+// Another possible design choice that I made without any real reason is
+// parameterizing the raw table over keys and values. Technically, all we need
+// is the size and alignment of keys and values, and the code should be just as
+// efficient (well, we might need one for power-of-two size and one for not...).
+// This has the potential to reduce code bloat in rust executables, without
+// really losing anything except 4 words (key size, key alignment, val size,
+// val alignment) which can be passed in to every call of a `RawTable` function.
+// This would definitely be an avenue worth exploring if people start complaining
+// about the size of rust executables.
+//
+// Annotate exceedingly likely branches in `table::make_hash`
+// and `search_hashed_generic` to reduce instruction cache pressure
+// and mispredictions once it becomes possible (blocked on issue #11092).
+//
+// Shrinking the table could simply reallocate in place after moving buckets
+// to the first half.
+//
+// The growth algorithm (fragment of the Proof of Correctness)
+// --------------------
+//
+// The growth algorithm is basically a fast path of the naive reinsertion-
+// during-resize algorithm. Other paths should never be taken.
+//
+// Consider growing a robin hood hashtable of capacity n. Normally, we do this
+// by allocating a new table of capacity `2n`, and then individually reinsert
+// each element in the old table into the new one. This guarantees that the
+// new table is a valid robin hood hashtable with all the desired statistical
+// properties. Remark that the order we reinsert the elements in should not
+// matter. For simplicity and efficiency, we will consider only linear
+// reinsertions, which consist of reinserting all elements in the old table
+// into the new one by increasing order of index. However we will not be
+// starting our reinsertions from index 0 in general. If we start from index
+// i, for the purpose of reinsertion we will consider all elements with real
+// index j < i to have virtual index n + j.
+//
+// Our hash generation scheme consists of generating a 64-bit hash and
+// truncating the most significant bits. When moving to the new table, we
+// simply introduce a new bit to the front of the hash. Therefore, if an
+// elements has ideal index i in the old table, it can have one of two ideal
+// locations in the new table. If the new bit is 0, then the new ideal index
+// is i. If the new bit is 1, then the new ideal index is n + i. Intutively,
+// we are producing two independent tables of size n, and for each element we
+// independently choose which table to insert it into with equal probability.
+// However the rather than wrapping around themselves on overflowing their
+// indexes, the first table overflows into the first, and the first into the
+// second. Visually, our new table will look something like:
+//
+// [yy_xxx_xxxx_xxx|xx_yyy_yyyy_yyy]
+//
+// Where x's are elements inserted into the first table, y's are elements
+// inserted into the second, and _'s are empty sections. We now define a few
+// key concepts that we will use later. Note that this is a very abstract
+// perspective of the table. A real resized table would be at least half
+// empty.
+//
+// Theorem: A linear robin hood reinsertion from the first ideal element
+// produces identical results to a linear naive reinsertion from the same
+// element.
+//
+// FIXME(Gankro, pczarn): review the proof and put it all in a separate doc.rs
+
+/// A hash map implementation which uses linear probing with Robin
+/// Hood bucket stealing.
+///
+/// The hashes are all keyed by the task-local random number generator
+/// on creation by default. This means that the ordering of the keys is
+/// randomized, but makes the tables more resistant to
+/// denial-of-service attacks (Hash DoS). This behaviour can be
+/// overridden with one of the constructors.
+///
+/// It is required that the keys implement the `Eq` and `Hash` traits, although
+/// this can frequently be achieved by using `#[deriving(Eq, Hash)]`.
+///
+/// Relevant papers/articles:
+///
+/// 1. Pedro Celis. ["Robin Hood Hashing"](https://cs.uwaterloo.ca/research/tr/1986/CS-86-14.pdf)
+/// 2. Emmanuel Goossaert. ["Robin Hood
+/// hashing"](http://codecapsule.com/2013/11/11/robin-hood-hashing/)
+/// 3. Emmanuel Goossaert. ["Robin Hood hashing: backward shift
+/// deletion"](http://codecapsule.com/2013/11/17/robin-hood-hashing-backward-shift-deletion/)
+///
+/// # Example
+///
+/// ```
+/// use std::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 Huckleberry Finn", "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);
+/// }
+/// ```
+///
+/// The easiest way to use `HashMap` with a custom type is to derive `Eq` and `Hash`.
+/// We must also derive `PartialEq`.
+///
+/// ```
+/// use std::collections::HashMap;
+///
+/// #[deriving(Hash, Eq, PartialEq, Show)]
+/// struct Viking<'a> {
+/// name: &'a str,
+/// power: uint,
+/// }
+///
+/// let mut vikings = HashMap::new();
+///
+/// vikings.insert("Norway", Viking { name: "Einar", power: 9u });
+/// vikings.insert("Denmark", Viking { name: "Olaf", power: 4u });
+/// vikings.insert("Iceland", Viking { name: "Harald", power: 8u });
+///
+/// // Use derived implementation to print the vikings.
+/// for (land, viking) in vikings.iter() {
+/// println!("{} at {}", viking, land);
+/// }
+/// ```
+#[deriving(Clone)]
+pub struct HashMap<K, V, H = RandomSipHasher> {
+ // All hashes are keyed on these values, to prevent hash collision attacks.
+ hasher: H,
+
+ table: RawTable<K, V>,
+
+ // We keep this at the end since it might as well have tail padding.
+ resize_policy: DefaultResizePolicy,
+}
+
+/// Search for a pre-hashed key.
+fn search_hashed_generic<K, V, M: Deref<RawTable<K, V>>>(table: M,
+ hash: &SafeHash,
+ is_match: |&K| -> bool)
+ -> SearchResult<K, V, M> {
+ let size = table.size();
+ let mut probe = Bucket::new(table, hash);
+ let ib = probe.index();
+
+ while probe.index() != ib + size {
+ let full = match probe.peek() {
+ Empty(b) => return TableRef(b.into_table()), // hit an empty bucket
+ Full(b) => b
+ };
+
+ if full.distance() + ib < full.index() {
+ // We can finish the search early if we hit any bucket
+ // with a lower distance to initial bucket than we've probed.
+ return TableRef(full.into_table());
+ }
+
+ // If the hash doesn't match, it can't be this one..
+ if *hash == full.hash() {
+ let matched = {
+ let (k, _) = full.read();
+ is_match(k)
+ };
+
+ // If the key doesn't match, it can't be this one..
+ if matched {
+ return FoundExisting(full);
+ }
+ }
+
+ probe = full.next();
+ }
+
+ TableRef(probe.into_table())
+}
+
+fn search_hashed<K: Eq, V, M: Deref<RawTable<K, V>>>(table: M, hash: &SafeHash, k: &K)
+ -> SearchResult<K, V, M> {
+ search_hashed_generic(table, hash, |k_| *k == *k_)
+}
+
+fn pop_internal<K, V>(starting_bucket: FullBucketMut<K, V>) -> (K, V) {
+ let (empty, retkey, retval) = starting_bucket.take();
+ let mut gap = match empty.gap_peek() {
+ Some(b) => b,
+ None => return (retkey, retval)
+ };
+
+ while gap.full().distance() != 0 {
+ gap = match gap.shift() {
+ Some(b) => b,
+ None => break
+ };
+ }
+
+ // Now we've done all our shifting. Return the value we grabbed earlier.
+ return (retkey, retval);
+}
+
+/// Perform robin hood bucket stealing at the given `bucket`. You must
+/// also pass the position of that bucket's initial bucket so we don't have
+/// to recalculate it.
+///
+/// `hash`, `k`, and `v` are the elements to "robin hood" into the hashtable.
+fn robin_hood<'a, K: 'a, V: 'a>(mut bucket: FullBucketMut<'a, K, V>,
+ mut ib: uint,
+ mut hash: SafeHash,
+ mut k: K,
+ mut v: V)
+ -> &'a mut V {
+ let starting_index = bucket.index();
+ let size = {
+ let table = bucket.table(); // FIXME "lifetime too short".
+ table.size()
+ };
+ // There can be at most `size - dib` buckets to displace, because
+ // in the worst case, there are `size` elements and we already are
+ // `distance` buckets away from the initial one.
+ let idx_end = starting_index + size - bucket.distance();
+
+ loop {
+ let (old_hash, old_key, old_val) = bucket.replace(hash, k, v);
+ loop {
+ let probe = bucket.next();
+ assert!(probe.index() != idx_end);
+
+ let full_bucket = match probe.peek() {
+ table::Empty(bucket) => {
+ // Found a hole!
+ let b = bucket.put(old_hash, old_key, old_val);
+ // Now that it's stolen, just read the value's pointer
+ // right out of the table!
+ let (_, v) = Bucket::at_index(b.into_table(), starting_index).peek()
+ .expect_full()
+ .into_mut_refs();
+ return v;
+ },
+ table::Full(bucket) => bucket
+ };
+
+ let probe_ib = full_bucket.index() - full_bucket.distance();
+
+ bucket = full_bucket;
+
+ // Robin hood! Steal the spot.
+ if ib < probe_ib {
+ ib = probe_ib;
+ hash = old_hash;
+ k = old_key;
+ v = old_val;
+ break;
+ }
+ }
+ }
+}
+
+/// A result that works like Option<FullBucket<..>> but preserves
+/// the reference that grants us access to the table in any case.
+enum SearchResult<K, V, M> {
+ // This is an entry that holds the given key:
+ FoundExisting(FullBucket<K, V, M>),
+
+ // There was no such entry. The reference is given back:
+ TableRef(M)
+}
+
+impl<K, V, M> SearchResult<K, V, M> {
+ fn into_option(self) -> Option<FullBucket<K, V, M>> {
+ match self {
+ FoundExisting(bucket) => Some(bucket),
+ TableRef(_) => None
+ }
+ }
+}
+
+impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
+ fn make_hash<Sized? X: Hash<S>>(&self, x: &X) -> SafeHash {
+ table::make_hash(&self.hasher, x)
+ }
+
+ fn search_equiv<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a self, q: &Q)
+ -> Option<FullBucketImm<'a, K, V>> {
+ let hash = self.make_hash(q);
+ search_hashed_generic(&self.table, &hash, |k| q.equiv(k)).into_option()
+ }
+
+ fn search_equiv_mut<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a mut self, q: &Q)
+ -> Option<FullBucketMut<'a, K, V>> {
+ let hash = self.make_hash(q);
+ search_hashed_generic(&mut self.table, &hash, |k| q.equiv(k)).into_option()
+ }
+
+ /// Search for a key, yielding the index if it's found in the hashtable.
+ /// If you already have the hash for the key lying around, use
+ /// search_hashed.
+ fn search<'a>(&'a self, k: &K) -> Option<FullBucketImm<'a, K, V>> {
+ let hash = self.make_hash(k);
+ search_hashed(&self.table, &hash, k).into_option()
+ }
+
+ fn search_mut<'a>(&'a mut self, k: &K) -> Option<FullBucketMut<'a, K, V>> {
+ let hash = self.make_hash(k);
+ search_hashed(&mut self.table, &hash, k).into_option()
+ }
+
+ // The caller should ensure that invariants by Robin Hood Hashing hold.
+ fn insert_hashed_ordered(&mut self, hash: SafeHash, k: K, v: V) {
+ let cap = self.table.capacity();
+ let mut buckets = Bucket::new(&mut self.table, &hash);
+ let ib = buckets.index();
+
+ while buckets.index() != ib + cap {
+ // We don't need to compare hashes for value swap.
+ // Not even DIBs for Robin Hood.
+ buckets = match buckets.peek() {
+ Empty(empty) => {
+ empty.put(hash, k, v);
+ return;
+ }
+ Full(b) => b.into_bucket()
+ };
+ buckets.next();
+ }
+ panic!("Internal HashMap error: Out of space.");
+ }
+}
+
+impl<K: Hash + Eq, V> HashMap<K, V, RandomSipHasher> {
+ /// Create an empty HashMap.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ /// let mut map: HashMap<&str, int> = HashMap::with_capacity(10);
+ /// ```
+ #[inline]
+ pub fn new() -> HashMap<K, V, RandomSipHasher> {
+ let hasher = RandomSipHasher::new();
+ HashMap::with_hasher(hasher)
+ }
+
+ /// Creates an empty hash map with the given initial capacity.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ /// let mut map: HashMap<&str, int> = HashMap::with_capacity(10);
+ /// ```
+ #[inline]
+ pub fn with_capacity(capacity: uint) -> HashMap<K, V, RandomSipHasher> {
+ let hasher = RandomSipHasher::new();
+ HashMap::with_capacity_and_hasher(capacity, hasher)
+ }
+}
+
+impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
+ /// Creates an empty hashmap which will use the given hasher to hash keys.
+ ///
+ /// The creates map has the default initial capacity.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ /// use std::hash::sip::SipHasher;
+ ///
+ /// let h = SipHasher::new();
+ /// let mut map = HashMap::with_hasher(h);
+ /// map.insert(1i, 2u);
+ /// ```
+ #[inline]
+ pub fn with_hasher(hasher: H) -> HashMap<K, V, H> {
+ HashMap {
+ hasher: hasher,
+ resize_policy: DefaultResizePolicy::new(INITIAL_CAPACITY),
+ table: RawTable::new(0),
+ }
+ }
+
+ /// Create an empty HashMap with space for at least `capacity`
+ /// elements, using `hasher` to hash the keys.
+ ///
+ /// Warning: `hasher` is normally randomly generated, and
+ /// is designed to allow HashMaps to be resistant to attacks that
+ /// cause many collisions and very poor performance. Setting it
+ /// manually using this function can expose a DoS attack vector.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ /// use std::hash::sip::SipHasher;
+ ///
+ /// let h = SipHasher::new();
+ /// let mut map = HashMap::with_capacity_and_hasher(10, h);
+ /// map.insert(1i, 2u);
+ /// ```
+ #[inline]
+ pub fn with_capacity_and_hasher(capacity: uint, hasher: H) -> HashMap<K, V, H> {
+ let cap = num::next_power_of_two(max(INITIAL_CAPACITY, capacity));
+ HashMap {
+ hasher: hasher,
+ resize_policy: DefaultResizePolicy::new(cap),
+ table: RawTable::new(cap),
+ }
+ }
+
+ /// The hashtable will never try to shrink below this size. You can use
+ /// this function to reduce reallocations if your hashtable frequently
+ /// grows and shrinks by large amounts.
+ ///
+ /// This function has no effect on the operational semantics of the
+ /// hashtable, only on performance.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ /// let mut map: HashMap<&str, int> = HashMap::new();
+ /// map.reserve(10);
+ /// ```
+ pub fn reserve(&mut self, new_minimum_capacity: uint) {
+ let cap = num::next_power_of_two(
+ max(INITIAL_CAPACITY, new_minimum_capacity));
+
+ self.resize_policy.reserve(cap);
+
+ if self.table.capacity() < cap {
+ self.resize(cap);
+ }
+ }
+
+ /// Resizes the internal vectors to a new capacity. It's your responsibility to:
+ /// 1) Make sure the new capacity is enough for all the elements, accounting
+ /// for the load factor.
+ /// 2) Ensure new_capacity is a power of two.
+ fn resize(&mut self, new_capacity: uint) {
+ assert!(self.table.size() <= new_capacity);
+ assert!(num::is_power_of_two(new_capacity));
+
+ let mut old_table = replace(&mut self.table, RawTable::new(new_capacity));
+ let old_size = old_table.size();
+
+ if old_table.capacity() == 0 || old_table.size() == 0 {
+ return;
+ }
+
+ if new_capacity < old_table.capacity() {
+ // Shrink the table. Naive algorithm for resizing:
+ for (h, k, v) in old_table.into_iter() {
+ self.insert_hashed_nocheck(h, k, v);
+ }
+ } else {
+ // Grow the table.
+ // Specialization of the other branch.
+ let mut bucket = Bucket::first(&mut old_table);
+
+ // "So a few of the first shall be last: for many be called,
+ // but few chosen."
+ //
+ // We'll most likely encounter a few buckets at the beginning that
+ // have their initial buckets near the end of the table. They were
+ // placed at the beginning as the probe wrapped around the table
+ // during insertion. We must skip forward to a bucket that won't
+ // get reinserted too early and won't unfairly steal others spot.
+ // This eliminates the need for robin hood.
+ loop {
+ bucket = match bucket.peek() {
+ Full(full) => {
+ if full.distance() == 0 {
+ // This bucket occupies its ideal spot.
+ // It indicates the start of another "cluster".
+ bucket = full.into_bucket();
+ break;
+ }
+ // Leaving this bucket in the last cluster for later.
+ full.into_bucket()
+ }
+ Empty(b) => {
+ // Encountered a hole between clusters.
+ b.into_bucket()
+ }
+ };
+ bucket.next();
+ }
+
+ // This is how the buckets might be laid out in memory:
+ // ($ marks an initialized bucket)
+ // ________________
+ // |$$$_$$$$$$_$$$$$|
+ //
+ // But we've skipped the entire initial cluster of buckets
+ // and will continue iteration in this order:
+ // ________________
+ // |$$$$$$_$$$$$
+ // ^ wrap around once end is reached
+ // ________________
+ // $$$_____________|
+ // ^ exit once table.size == 0
+ loop {
+ bucket = match bucket.peek() {
+ Full(bucket) => {
+ let h = bucket.hash();
+ let (b, k, v) = bucket.take();
+ self.insert_hashed_ordered(h, k, v);
+ {
+ let t = b.table(); // FIXME "lifetime too short".
+ if t.size() == 0 { break }
+ };
+ b.into_bucket()
+ }
+ Empty(b) => b.into_bucket()
+ };
+ bucket.next();
+ }
+ }
+
+ assert_eq!(self.table.size(), old_size);
+ }
+
+ /// Performs any necessary resize operations, such that there's space for
+ /// new_size elements.
+ fn make_some_room(&mut self, new_size: uint) {
+ let (grow_at, shrink_at) = self.resize_policy.capacity_range(new_size);
+ let cap = self.table.capacity();
+
+ // An invalid value shouldn't make us run out of space.
+ debug_assert!(grow_at >= new_size);
+
+ if cap <= grow_at {
+ let new_capacity = max(cap << 1, INITIAL_CAPACITY);
+ self.resize(new_capacity);
+ } else if shrink_at <= cap {
+ let new_capacity = cap >> 1;
+ self.resize(new_capacity);
+ }
+ }
+
+ /// Insert a pre-hashed key-value pair, without first checking
+ /// that there's enough room in the buckets. Returns a reference to the
+ /// newly insert value.
+ ///
+ /// If the key already exists, the hashtable will be returned untouched
+ /// and a reference to the existing element will be returned.
+ fn insert_hashed_nocheck(&mut self, hash: SafeHash, k: K, v: V) -> &mut V {
+ self.insert_or_replace_with(hash, k, v, |_, _, _| ())
+ }
+
+ fn insert_or_replace_with<'a>(&'a mut self,
+ hash: SafeHash,
+ k: K,
+ v: V,
+ found_existing: |&mut K, &mut V, V|)
+ -> &'a mut V {
+ // Worst case, we'll find one empty bucket among `size + 1` buckets.
+ let size = self.table.size();
+ let mut probe = Bucket::new(&mut self.table, &hash);
+ let ib = probe.index();
+
+ loop {
+ let mut bucket = match probe.peek() {
+ Empty(bucket) => {
+ // Found a hole!
+ let bucket = bucket.put(hash, k, v);
+ let (_, val) = bucket.into_mut_refs();
+ return val;
+ },
+ Full(bucket) => bucket
+ };
+
+ if bucket.hash() == hash {
+ let found_match = {
+ let (bucket_k, _) = bucket.read_mut();
+ k == *bucket_k
+ };
+ if found_match {
+ let (bucket_k, bucket_v) = bucket.into_mut_refs();
+ debug_assert!(k == *bucket_k);
+ // Key already exists. Get its reference.
+ found_existing(bucket_k, bucket_v, v);
+ return bucket_v;
+ }
+ }
+
+ let robin_ib = bucket.index() as int - bucket.distance() as int;
+
+ if (ib as int) < robin_ib {
+ // Found a luckier bucket than me. Better steal his spot.
+ return robin_hood(bucket, robin_ib as uint, hash, k, v);
+ }
+
+ probe = bucket.next();
+ assert!(probe.index() != ib + size + 1);
+ }
+ }
+
+ /// Retrieves a mutable value for the given key.
+ /// See [`find_mut`](../trait.MutableMap.html#tymethod.find_mut) for a non-panicking
+ /// alternative.
+ ///
+ /// # Failure
+ ///
+ /// Fails if the key is not present.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # #![allow(deprecated)]
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert("a", 1i);
+ /// {
+ /// // val will freeze map to prevent usage during its lifetime
+ /// let val = map.get_mut(&"a");
+ /// *val = 40;
+ /// }
+ /// assert_eq!(map["a"], 40);
+ ///
+ /// // A more direct way could be:
+ /// *map.get_mut(&"a") = -2;
+ /// assert_eq!(map["a"], -2);
+ /// ```
+ #[deprecated = "use indexing instead: `&mut map[key]`"]
+ pub fn get_mut<'a>(&'a mut self, k: &K) -> &'a mut V {
+ &mut self[*k]
+ }
+
+ /// Return true if the map contains a value for the specified key,
+ /// using equivalence.
+ ///
+ /// See [pop_equiv](#method.pop_equiv) for an extended example.
+ pub fn contains_key_equiv<Sized? Q: Hash<S> + Equiv<K>>(&self, key: &Q) -> bool {
+ self.search_equiv(key).is_some()
+ }
+
+ /// Return the value corresponding to the key in the map, using
+ /// equivalence.
+ ///
+ /// See [pop_equiv](#method.pop_equiv) for an extended example.
+ pub fn find_equiv<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a self, k: &Q) -> Option<&'a V> {
+ match self.search_equiv(k) {
+ None => None,
+ Some(bucket) => {
+ let (_, v_ref) = bucket.into_refs();
+ Some(v_ref)
+ }
+ }
+ }
+
+ /// Remove an equivalent key from the map, returning the value at the
+ /// key if the key was previously in the map.
+ ///
+ /// # Example
+ ///
+ /// This is a slightly silly example where we define the number's
+ /// parity as the equivalence class. It is important that the
+ /// values hash the same, which is why we implement `Hash`.
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ /// use std::hash::Hash;
+ /// use std::hash::sip::SipState;
+ ///
+ /// #[deriving(Eq, PartialEq)]
+ /// struct EvenOrOdd {
+ /// num: uint
+ /// };
+ ///
+ /// impl Hash for EvenOrOdd {
+ /// fn hash(&self, state: &mut SipState) {
+ /// let parity = self.num % 2;
+ /// parity.hash(state);
+ /// }
+ /// }
+ ///
+ /// impl Equiv<EvenOrOdd> for EvenOrOdd {
+ /// fn equiv(&self, other: &EvenOrOdd) -> bool {
+ /// self.num % 2 == other.num % 2
+ /// }
+ /// }
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert(EvenOrOdd { num: 3 }, "foo");
+ ///
+ /// assert!(map.contains_key_equiv(&EvenOrOdd { num: 1 }));
+ /// assert!(!map.contains_key_equiv(&EvenOrOdd { num: 4 }));
+ ///
+ /// assert_eq!(map.find_equiv(&EvenOrOdd { num: 5 }), Some(&"foo"));
+ /// assert_eq!(map.find_equiv(&EvenOrOdd { num: 2 }), None);
+ ///
+ /// assert_eq!(map.pop_equiv(&EvenOrOdd { num: 1 }), Some("foo"));
+ /// assert_eq!(map.pop_equiv(&EvenOrOdd { num: 2 }), None);
+ ///
+ /// ```
+ #[experimental]
+ pub fn pop_equiv<Sized? Q:Hash<S> + Equiv<K>>(&mut self, k: &Q) -> Option<V> {
+ if self.table.size() == 0 {
+ return None
+ }
+
+ let potential_new_size = self.table.size() - 1;
+ self.make_some_room(potential_new_size);
+
+ match self.search_equiv_mut(k) {
+ Some(bucket) => {
+ let (_k, val) = pop_internal(bucket);
+ Some(val)
+ }
+ _ => None
+ }
+ }
+
+ /// An iterator visiting all keys in arbitrary order.
+ /// Iterator element type is `&'a K`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert("a", 1i);
+ /// map.insert("b", 2);
+ /// map.insert("c", 3);
+ ///
+ /// for key in map.keys() {
+ /// println!("{}", key);
+ /// }
+ /// ```
+ pub fn keys(&self) -> Keys<K, V> {
+ self.iter().map(|(k, _v)| k)
+ }
+
+ /// An iterator visiting all values in arbitrary order.
+ /// Iterator element type is `&'a V`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert("a", 1i);
+ /// map.insert("b", 2);
+ /// map.insert("c", 3);
+ ///
+ /// for key in map.values() {
+ /// println!("{}", key);
+ /// }
+ /// ```
+ pub fn values(&self) -> Values<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)`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert("a", 1i);
+ /// map.insert("b", 2);
+ /// map.insert("c", 3);
+ ///
+ /// for (key, val) in map.iter() {
+ /// println!("key: {} val: {}", key, val);
+ /// }
+ /// ```
+ pub fn iter(&self) -> Entries<K, V> {
+ Entries { inner: self.table.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)`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert("a", 1i);
+ /// map.insert("b", 2);
+ /// map.insert("c", 3);
+ ///
+ /// // Update all values
+ /// for (_, val) in map.iter_mut() {
+ /// *val *= 2;
+ /// }
+ ///
+ /// for (key, val) in map.iter() {
+ /// println!("key: {} val: {}", key, val);
+ /// }
+ /// ```
+ pub fn iter_mut(&mut self) -> MutEntries<K, V> {
+ MutEntries { inner: self.table.iter_mut() }
+ }
+
+ /// 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.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert("a", 1i);
+ /// map.insert("b", 2);
+ /// map.insert("c", 3);
+ ///
+ /// // Not possible with .iter()
+ /// let vec: Vec<(&str, int)> = map.into_iter().collect();
+ /// ```
+ pub fn into_iter(self) -> MoveEntries<K, V> {
+ MoveEntries {
+ inner: self.table.into_iter().map(|(_, k, v)| (k, v))
+ }
+ }
+
+ /// Gets the given key's corresponding entry in the map for in-place manipulation
+ pub fn entry<'a>(&'a mut self, key: K) -> Entry<'a, K, V> {
+ // Gotta resize now, and we don't know which direction, so try both?
+ let size = self.table.size();
+ self.make_some_room(size + 1);
+ if size > 0 {
+ self.make_some_room(size - 1);
+ }
+
+ let hash = self.make_hash(&key);
+ search_entry_hashed(&mut self.table, hash, key)
+ }
+
+ /// Return the number of elements in the map.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut a = HashMap::new();
+ /// assert_eq!(a.len(), 0);
+ /// a.insert(1u, "a");
+ /// assert_eq!(a.len(), 1);
+ /// ```
+ pub fn len(&self) -> uint { self.table.size() }
+
+ /// Return true if the map contains no elements.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut a = HashMap::new();
+ /// assert!(a.is_empty());
+ /// a.insert(1u, "a");
+ /// assert!(!a.is_empty());
+ /// ```
+ #[inline]
+ pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+ /// Clears the map, removing all key-value pairs. Keeps the allocated memory
+ /// for reuse.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut a = HashMap::new();
+ /// a.insert(1u, "a");
+ /// a.clear();
+ /// assert!(a.is_empty());
+ /// ```
+ pub fn clear(&mut self) {
+ // Prevent reallocations from happening from now on. Makes it possible
+ // for the map to be reused but has a downside: reserves permanently.
+ self.resize_policy.reserve(self.table.size());
+
+ let cap = self.table.capacity();
+ let mut buckets = Bucket::first(&mut self.table);
+
+ while buckets.index() != cap {
+ buckets = match buckets.peek() {
+ Empty(b) => b.next(),
+ Full(full) => {
+ let (b, _, _) = full.take();
+ b.next()
+ }
+ };
+ }
+ }
+
+ /// Returns a reference to the value corresponding to the key.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert(1u, "a");
+ /// assert_eq!(map.find(&1), Some(&"a"));
+ /// assert_eq!(map.find(&2), None);
+ /// ```
+ pub fn find<'a>(&'a self, k: &K) -> Option<&'a V> {
+ self.search(k).map(|bucket| {
+ let (_, v) = bucket.into_refs();
+ v
+ })
+ }
+
+ /// Returns true if the map contains a value for the specified key.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert(1u, "a");
+ /// assert_eq!(map.contains_key(&1), true);
+ /// assert_eq!(map.contains_key(&2), false);
+ /// ```
+ pub fn contains_key(&self, k: &K) -> bool {
+ self.search(k).is_some()
+ }
+
+ /// Returns a mutable reference to the value corresponding to the key.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert(1u, "a");
+ /// match map.find_mut(&1) {
+ /// Some(x) => *x = "b",
+ /// None => (),
+ /// }
+ /// assert_eq!(map[1], "b");
+ /// ```
+ pub fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> {
+ match self.search_mut(k) {
+ Some(bucket) => {
+ let (_, v) = bucket.into_mut_refs();
+ Some(v)
+ }
+ _ => None
+ }
+ }
+
+ /// Inserts a key-value pair into the map. An existing value for a
+ /// key is replaced by the new value. Returns `true` if the key did
+ /// not already exist in the map.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// assert_eq!(map.insert(2u, "value"), true);
+ /// assert_eq!(map.insert(2, "value2"), false);
+ /// assert_eq!(map[2], "value2");
+ /// ```
+ #[inline]
+ pub fn insert(&mut self, key: K, value: V) -> bool {
+ self.swap(key, value).is_none()
+ }
+
+ /// Removes a key-value pair from the map. Returns `true` if the key
+ /// was present in the map.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// assert_eq!(map.remove(&1u), false);
+ /// map.insert(1, "a");
+ /// assert_eq!(map.remove(&1), true);
+ /// ```
+ #[inline]
+ pub fn remove(&mut self, key: &K) -> bool {
+ self.pop(key).is_some()
+ }
+
+ /// Inserts a key-value pair from the map. If the key already had a value
+ /// present in the map, that value is returned. Otherwise, `None` is returned.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// assert_eq!(map.swap(37u, "a"), None);
+ /// assert_eq!(map.is_empty(), false);
+ ///
+ /// map.insert(37, "b");
+ /// assert_eq!(map.swap(37, "c"), Some("b"));
+ /// assert_eq!(map[37], "c");
+ /// ```
+ pub fn swap(&mut self, k: K, v: V) -> Option<V> {
+ let hash = self.make_hash(&k);
+ let potential_new_size = self.table.size() + 1;
+ self.make_some_room(potential_new_size);
+
+ let mut retval = None;
+ self.insert_or_replace_with(hash, k, v, |_, val_ref, val| {
+ retval = Some(replace(val_ref, val));
+ });
+ retval
+ }
+
+ /// Removes a key from the map, returning the value at the key if the key
+ /// was previously in the map.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert(1u, "a");
+ /// assert_eq!(map.pop(&1), Some("a"));
+ /// assert_eq!(map.pop(&1), None);
+ /// ```
+ pub fn pop(&mut self, k: &K) -> Option<V> {
+ if self.table.size() == 0 {
+ return None
+ }
+
+ let potential_new_size = self.table.size() - 1;
+ self.make_some_room(potential_new_size);
+
+ self.search_mut(k).map(|bucket| {
+ let (_k, val) = pop_internal(bucket);
+ val
+ })
+ }
+}
+
+fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable<K,V>, hash: SafeHash, k: K)
+ -> Entry<'a, K, V> {
+ // Worst case, we'll find one empty bucket among `size + 1` buckets.
+ let size = table.size();
+ let mut probe = Bucket::new(table, &hash);
+ let ib = probe.index();
+
+ loop {
+ let bucket = match probe.peek() {
+ Empty(bucket) => {
+ // Found a hole!
+ return Vacant(VacantEntry {
+ hash: hash,
+ key: k,
+ elem: NoElem(bucket),
+ });
+ },
+ Full(bucket) => bucket
+ };
+
+ if bucket.hash() == hash {
+ let is_eq = {
+ let (bucket_k, _) = bucket.read();
+ k == *bucket_k
+ };
+
+ if is_eq {
+ return Occupied(OccupiedEntry{
+ elem: bucket,
+ });
+ }
+ }
+
+ let robin_ib = bucket.index() as int - bucket.distance() as int;
+
+ if (ib as int) < robin_ib {
+ // Found a luckier bucket than me. Better steal his spot.
+ return Vacant(VacantEntry {
+ hash: hash,
+ key: k,
+ elem: NeqElem(bucket, robin_ib as uint),
+ });
+ }
+
+ probe = bucket.next();
+ assert!(probe.index() != ib + size + 1);
+ }
+}
+
+impl<K: Eq + Hash<S>, V: Clone, S, H: Hasher<S>> HashMap<K, V, H> {
+ /// Return a copy of the value corresponding to the key.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map: HashMap<uint, String> = HashMap::new();
+ /// map.insert(1u, "foo".to_string());
+ /// let s: String = map.find_copy(&1).unwrap();
+ /// ```
+ pub fn find_copy(&self, k: &K) -> Option<V> {
+ self.find(k).map(|v| (*v).clone())
+ }
+
+ /// Return a copy of the value corresponding to the key.
+ ///
+ /// # Failure
+ ///
+ /// Fails if the key is not present.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map: HashMap<uint, String> = HashMap::new();
+ /// map.insert(1u, "foo".to_string());
+ /// let s: String = map.get_copy(&1);
+ /// ```
+ pub fn get_copy(&self, k: &K) -> V {
+ self[*k].clone()
+ }
+}
+
+impl<K: Eq + Hash<S>, V: PartialEq, S, H: Hasher<S>> PartialEq for HashMap<K, V, H> {
+ fn eq(&self, other: &HashMap<K, V, H>) -> bool {
+ if self.len() != other.len() { return false; }
+
+ self.iter().all(|(key, value)|
+ other.find(key).map_or(false, |v| *value == *v)
+ )
+ }
+}
+
+impl<K: Eq + Hash<S>, V: Eq, S, H: Hasher<S>> Eq for HashMap<K, V, H> {}
+
+impl<K: Eq + Hash<S> + Show, V: Show, S, H: Hasher<S>> Show for HashMap<K, V, H> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ try!(write!(f, "{{"));
+
+ for (i, (k, v)) in self.iter().enumerate() {
+ if i != 0 { try!(write!(f, ", ")); }
+ try!(write!(f, "{}: {}", *k, *v));
+ }
+
+ write!(f, "}}")
+ }
+}
+
+impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Default for HashMap<K, V, H> {
+ fn default() -> HashMap<K, V, H> {
+ HashMap::with_hasher(Default::default())
+ }
+}
+
+impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Index<K, V> for HashMap<K, V, H> {
+ #[inline]
+ fn index<'a>(&'a self, index: &K) -> &'a V {
+ self.find(index).expect("no entry found for key")
+ }
+}
+
+impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> IndexMut<K, V> for HashMap<K, V, H> {
+ #[inline]
+ fn index_mut<'a>(&'a mut self, index: &K) -> &'a mut V {
+ match self.find_mut(index) {
+ Some(v) => v,
+ None => panic!("no entry found for key")
+ }
+ }
+}
+
+/// HashMap iterator
+pub struct Entries<'a, K: 'a, V: 'a> {
+ inner: table::Entries<'a, K, V>
+}
+
+/// HashMap mutable values iterator
+pub struct MutEntries<'a, K: 'a, V: 'a> {
+ inner: table::MutEntries<'a, K, V>
+}
+
+/// HashMap move iterator
+pub struct MoveEntries<K, V> {
+ inner: iter::Map<'static, (SafeHash, K, V), (K, V), table::MoveEntries<K, V>>
+}
+
+/// A view into a single occupied location in a HashMap
+pub struct OccupiedEntry<'a, K:'a, V:'a> {
+ elem: FullBucket<K, V, &'a mut RawTable<K, V>>,
+}
+
+/// A view into a single empty location in a HashMap
+pub struct VacantEntry<'a, K:'a, V:'a> {
+ hash: SafeHash,
+ key: K,
+ elem: VacantEntryState<K,V, &'a mut RawTable<K, V>>,
+}
+
+/// A view into a single location in a map, which may be vacant or occupied
+pub enum Entry<'a, K:'a, V:'a> {
+ /// An occupied Entry
+ Occupied(OccupiedEntry<'a, K, V>),
+ /// A vacant Entry
+ Vacant(VacantEntry<'a, K, V>),
+}
+
+/// Possible states of a VacantEntry
+enum VacantEntryState<K, V, M> {
+ /// The index is occupied, but the key to insert has precedence,
+ /// and will kick the current one out on insertion
+ NeqElem(FullBucket<K, V, M>, uint),
+ /// The index is genuinely vacant
+ NoElem(EmptyBucket<K, V, M>),
+}
+
+impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
+ #[inline]
+ fn next(&mut self) -> Option<(&'a K, &'a V)> {
+ self.inner.next()
+ }
+ #[inline]
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ self.inner.size_hint()
+ }
+}
+
+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)> {
+ self.inner.next()
+ }
+ #[inline]
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ self.inner.size_hint()
+ }
+}
+
+impl<K, V> Iterator<(K, V)> for MoveEntries<K, V> {
+ #[inline]
+ fn next(&mut self) -> Option<(K, V)> {
+ self.inner.next()
+ }
+ #[inline]
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ self.inner.size_hint()
+ }
+}
+
+impl<'a, K, V> OccupiedEntry<'a, K, V> {
+ /// Gets a reference to the value in the entry
+ pub fn get(&self) -> &V {
+ let (_, v) = self.elem.read();
+ v
+ }
+
+ /// Gets a mutable reference to the value in the entry
+ pub fn get_mut(&mut self) -> &mut V {
+ let (_, v) = self.elem.read_mut();
+ v
+ }
+
+ /// Converts the OccupiedEntry into a mutable reference to the value in the entry
+ /// with a lifetime bound to the map itself
+ pub fn into_mut(self) -> &'a mut V {
+ let (_, v) = self.elem.into_mut_refs();
+ v
+ }
+
+ /// Sets the value of the entry, and returns the entry's old value
+ pub fn set(&mut self, mut value: V) -> V {
+ let old_value = self.get_mut();
+ mem::swap(&mut value, old_value);
+ value
+ }
+
+ /// Takes the value out of the entry, and returns it
+ pub fn take(self) -> V {
+ let (_, _, v) = self.elem.take();
+ v
+ }
+}
+
+impl<'a, K, V> VacantEntry<'a, K, V> {
+ /// Sets the value of the entry with the VacantEntry's key,
+ /// and returns a mutable reference to it
+ pub fn set(self, value: V) -> &'a mut V {
+ match self.elem {
+ NeqElem(bucket, ib) => {
+ robin_hood(bucket, ib, self.hash, self.key, value)
+ }
+ NoElem(bucket) => {
+ let full = bucket.put(self.hash, self.key, value);
+ let (_, v) = full.into_mut_refs();
+ 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>>;
+
+impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> FromIterator<(K, V)> for HashMap<K, V, H> {
+ fn from_iter<T: Iterator<(K, V)>>(iter: T) -> HashMap<K, V, H> {
+ let (lower, _) = iter.size_hint();
+ let mut map = HashMap::with_capacity_and_hasher(lower, Default::default());
+ map.extend(iter);
+ map
+ }
+}
+
+impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Extendable<(K, V)> for HashMap<K, V, H> {
+ fn extend<T: Iterator<(K, V)>>(&mut self, mut iter: T) {
+ for (k, v) in iter {
+ self.insert(k, v);
+ }
+ }
+}
+
+#[cfg(test)]
+mod test_map {
+ use prelude::*;
+
+ use super::HashMap;
+ use super::{Occupied, Vacant};
+ use cmp::Equiv;
+ use hash;
+ use iter::{Iterator,range_inclusive,range_step_inclusive};
+ use cell::RefCell;
+
+ struct KindaIntLike(int);
+
+ impl Equiv<int> for KindaIntLike {
+ fn equiv(&self, other: &int) -> bool {
+ let KindaIntLike(this) = *self;
+ this == *other
+ }
+ }
+ impl<S: hash::Writer> hash::Hash<S> for KindaIntLike {
+ fn hash(&self, state: &mut S) {
+ let KindaIntLike(this) = *self;
+ this.hash(state)
+ }
+ }
+
+ #[test]
+ fn test_create_capacity_zero() {
+ let mut m = HashMap::with_capacity(0);
+
+ assert!(m.insert(1i, 1i));
+
+ assert!(m.contains_key(&1));
+ assert!(!m.contains_key(&0));
+ }
+
+ #[test]
+ fn test_insert() {
+ let mut m = HashMap::new();
+ assert_eq!(m.len(), 0);
+ assert!(m.insert(1i, 2i));
+ assert_eq!(m.len(), 1);
+ assert!(m.insert(2i, 4i));
+ assert_eq!(m.len(), 2);
+ assert_eq!(*m.find(&1).unwrap(), 2);
+ assert_eq!(*m.find(&2).unwrap(), 4);
+ }
+
+ local_data_key!(drop_vector: RefCell<Vec<int>>)
+
+ #[deriving(Hash, PartialEq, Eq)]
+ struct Dropable {
+ k: uint
+ }
+
+ impl Dropable {
+ fn new(k: uint) -> Dropable {
+ let v = drop_vector.get().unwrap();
+ v.borrow_mut().as_mut_slice()[k] += 1;
+
+ Dropable { k: k }
+ }
+ }
+
+ impl Drop for Dropable {
+ fn drop(&mut self) {
+ let v = drop_vector.get().unwrap();
+ v.borrow_mut().as_mut_slice()[self.k] -= 1;
+ }
+ }
+
+ impl Clone for Dropable {
+ fn clone(&self) -> Dropable {
+ Dropable::new(self.k)
+ }
+ }
+
+ #[test]
+ fn test_drops() {
+ drop_vector.replace(Some(RefCell::new(Vec::from_elem(200, 0i))));
+
+ {
+ let mut m = HashMap::new();
+
+ let v = drop_vector.get().unwrap();
+ for i in range(0u, 200) {
+ assert_eq!(v.borrow().as_slice()[i], 0);
+ }
+ drop(v);
+
+ for i in range(0u, 100) {
+ let d1 = Dropable::new(i);
+ let d2 = Dropable::new(i+100);
+ m.insert(d1, d2);
+ }
+
+ let v = drop_vector.get().unwrap();
+ for i in range(0u, 200) {
+ assert_eq!(v.borrow().as_slice()[i], 1);
+ }
+ drop(v);
+
+ for i in range(0u, 50) {
+ let k = Dropable::new(i);
+ let v = m.pop(&k);
+
+ assert!(v.is_some());
+
+ let v = drop_vector.get().unwrap();
+ assert_eq!(v.borrow().as_slice()[i], 1);
+ assert_eq!(v.borrow().as_slice()[i+100], 1);
+ }
+
+ let v = drop_vector.get().unwrap();
+ for i in range(0u, 50) {
+ assert_eq!(v.borrow().as_slice()[i], 0);
+ assert_eq!(v.borrow().as_slice()[i+100], 0);
+ }
+
+ for i in range(50u, 100) {
+ assert_eq!(v.borrow().as_slice()[i], 1);
+ assert_eq!(v.borrow().as_slice()[i+100], 1);
+ }
+ }
+
+ let v = drop_vector.get().unwrap();
+ for i in range(0u, 200) {
+ assert_eq!(v.borrow().as_slice()[i], 0);
+ }
+ }
+
+ #[test]
+ fn test_move_iter_drops() {
+ drop_vector.replace(Some(RefCell::new(Vec::from_elem(200, 0i))));
+
+ let hm = {
+ let mut hm = HashMap::new();
+
+ let v = drop_vector.get().unwrap();
+ for i in range(0u, 200) {
+ assert_eq!(v.borrow().as_slice()[i], 0);
+ }
+ drop(v);
+
+ for i in range(0u, 100) {
+ let d1 = Dropable::new(i);
+ let d2 = Dropable::new(i+100);
+ hm.insert(d1, d2);
+ }
+
+ let v = drop_vector.get().unwrap();
+ for i in range(0u, 200) {
+ assert_eq!(v.borrow().as_slice()[i], 1);
+ }
+ drop(v);
+
+ hm
+ };
+
+ // By the way, ensure that cloning doesn't screw up the dropping.
+ drop(hm.clone());
+
+ {
+ let mut half = hm.into_iter().take(50);
+
+ let v = drop_vector.get().unwrap();
+ for i in range(0u, 200) {
+ assert_eq!(v.borrow().as_slice()[i], 1);
+ }
+ drop(v);
+
+ for _ in half {}
+
+ let v = drop_vector.get().unwrap();
+ let nk = range(0u, 100).filter(|&i| {
+ v.borrow().as_slice()[i] == 1
+ }).count();
+
+ let nv = range(0u, 100).filter(|&i| {
+ v.borrow().as_slice()[i+100] == 1
+ }).count();
+
+ assert_eq!(nk, 50);
+ assert_eq!(nv, 50);
+ };
+
+ let v = drop_vector.get().unwrap();
+ for i in range(0u, 200) {
+ assert_eq!(v.borrow().as_slice()[i], 0);
+ }
+ }
+
+ #[test]
+ fn test_empty_pop() {
+ let mut m: HashMap<int, bool> = HashMap::new();
+ assert_eq!(m.pop(&0), None);
+ }
+
+ #[test]
+ fn test_lots_of_insertions() {
+ let mut m = HashMap::new();
+
+ // Try this a few times to make sure we never screw up the hashmap's
+ // internal state.
+ for _ in range(0i, 10) {
+ assert!(m.is_empty());
+
+ for i in range_inclusive(1i, 1000) {
+ assert!(m.insert(i, i));
+
+ for j in range_inclusive(1, i) {
+ let r = m.find(&j);
+ assert_eq!(r, Some(&j));
+ }
+
+ for j in range_inclusive(i+1, 1000) {
+ let r = m.find(&j);
+ assert_eq!(r, None);
+ }
+ }
+
+ for i in range_inclusive(1001i, 2000) {
+ assert!(!m.contains_key(&i));
+ }
+
+ // remove forwards
+ for i in range_inclusive(1i, 1000) {
+ assert!(m.remove(&i));
+
+ for j in range_inclusive(1, i) {
+ assert!(!m.contains_key(&j));
+ }
+
+ for j in range_inclusive(i+1, 1000) {
+ assert!(m.contains_key(&j));
+ }
+ }
+
+ for i in range_inclusive(1i, 1000) {
+ assert!(!m.contains_key(&i));
+ }
+
+ for i in range_inclusive(1i, 1000) {
+ assert!(m.insert(i, i));
+ }
+
+ // remove backwards
+ for i in range_step_inclusive(1000i, 1, -1) {
+ assert!(m.remove(&i));
+
+ for j in range_inclusive(i, 1000) {
+ assert!(!m.contains_key(&j));
+ }
+
+ for j in range_inclusive(1, i-1) {
+ assert!(m.contains_key(&j));
+ }
+ }
+ }
+ }
+
+ #[test]
+ fn test_find_mut() {
+ let mut m = HashMap::new();
+ assert!(m.insert(1i, 12i));
+ assert!(m.insert(2i, 8i));
+ assert!(m.insert(5i, 14i));
+ let new = 100;
+ match m.find_mut(&5) {
+ None => panic!(), Some(x) => *x = new
+ }
+ assert_eq!(m.find(&5), Some(&new));
+ }
+
+ #[test]
+ fn test_insert_overwrite() {
+ let mut m = HashMap::new();
+ assert!(m.insert(1i, 2i));
+ assert_eq!(*m.find(&1).unwrap(), 2);
+ assert!(!m.insert(1i, 3i));
+ assert_eq!(*m.find(&1).unwrap(), 3);
+ }
+
+ #[test]
+ fn test_insert_conflicts() {
+ let mut m = HashMap::with_capacity(4);
+ assert!(m.insert(1i, 2i));
+ assert!(m.insert(5i, 3i));
+ assert!(m.insert(9i, 4i));
+ assert_eq!(*m.find(&9).unwrap(), 4);
+ assert_eq!(*m.find(&5).unwrap(), 3);
+ assert_eq!(*m.find(&1).unwrap(), 2);
+ }
+
+ #[test]
+ fn test_conflict_remove() {
+ let mut m = HashMap::with_capacity(4);
+ assert!(m.insert(1i, 2i));
+ assert_eq!(*m.find(&1).unwrap(), 2);
+ assert!(m.insert(5, 3));
+ assert_eq!(*m.find(&1).unwrap(), 2);
+ assert_eq!(*m.find(&5).unwrap(), 3);
+ assert!(m.insert(9, 4));
+ assert_eq!(*m.find(&1).unwrap(), 2);
+ assert_eq!(*m.find(&5).unwrap(), 3);
+ assert_eq!(*m.find(&9).unwrap(), 4);
+ assert!(m.remove(&1));
+ assert_eq!(*m.find(&9).unwrap(), 4);
+ assert_eq!(*m.find(&5).unwrap(), 3);
+ }
+
+ #[test]
+ fn test_is_empty() {
+ let mut m = HashMap::with_capacity(4);
+ assert!(m.insert(1i, 2i));
+ assert!(!m.is_empty());
+ assert!(m.remove(&1));
+ assert!(m.is_empty());
+ }
+
+ #[test]
+ fn test_pop() {
+ let mut m = HashMap::new();
+ m.insert(1i, 2i);
+ assert_eq!(m.pop(&1), Some(2));
+ assert_eq!(m.pop(&1), None);
+ }
+
+ #[test]
+ #[allow(experimental)]
+ fn test_pop_equiv() {
+ let mut m = HashMap::new();
+ m.insert(1i, 2i);
+ assert_eq!(m.pop_equiv(&KindaIntLike(1)), Some(2));
+ assert_eq!(m.pop_equiv(&KindaIntLike(1)), None);
+ }
+
+ #[test]
+ fn test_swap() {
+ let mut m = HashMap::new();
+ assert_eq!(m.swap(1i, 2i), None);
+ assert_eq!(m.swap(1i, 3i), Some(2));
+ assert_eq!(m.swap(1i, 4i), Some(3));
+ }
+
+ #[test]
+ fn test_iterate() {
+ let mut m = HashMap::with_capacity(4);
+ for i in range(0u, 32) {
+ assert!(m.insert(i, i*2));
+ }
+ assert_eq!(m.len(), 32);
+
+ let mut observed: u32 = 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 = vec![(1i, 'a'), (2i, 'b'), (3i, 'c')];
+ let map = vec.into_iter().collect::<HashMap<int, char>>();
+ let keys = map.keys().map(|&k| k).collect::<Vec<int>>();
+ assert_eq!(keys.len(), 3);
+ assert!(keys.contains(&1));
+ assert!(keys.contains(&2));
+ assert!(keys.contains(&3));
+ }
+
+ #[test]
+ fn test_values() {
+ let vec = vec![(1i, 'a'), (2i, 'b'), (3i, 'c')];
+ let map = vec.into_iter().collect::<HashMap<int, char>>();
+ let values = map.values().map(|&v| v).collect::<Vec<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(&1i).is_none());
+ m.insert(1i, 2i);
+ match m.find(&1) {
+ None => panic!(),
+ Some(v) => assert_eq!(*v, 2)
+ }
+ }
+
+ #[test]
+ fn test_find_copy() {
+ let mut m = HashMap::new();
+ assert!(m.find(&1i).is_none());
+
+ for i in range(1i, 10000) {
+ m.insert(i, i + 7);
+ match m.find_copy(&i) {
+ None => panic!(),
+ Some(v) => assert_eq!(v, i + 7)
+ }
+ for j in range(1i, i/100) {
+ match m.find_copy(&j) {
+ None => panic!(),
+ Some(v) => assert_eq!(v, j + 7)
+ }
+ }
+ }
+ }
+
+ #[test]
+ fn test_eq() {
+ let mut m1 = HashMap::new();
+ m1.insert(1i, 2i);
+ m1.insert(2i, 3i);
+ m1.insert(3i, 4i);
+
+ let mut m2 = HashMap::new();
+ m2.insert(1i, 2i);
+ m2.insert(2i, 3i);
+
+ assert!(m1 != m2);
+
+ m2.insert(3i, 4i);
+
+ assert_eq!(m1, m2);
+ }
+
+ #[test]
+ fn test_show() {
+ let mut map: HashMap<int, int> = HashMap::new();
+ let empty: HashMap<int, int> = HashMap::new();
+
+ map.insert(1i, 2i);
+ map.insert(3i, 4i);
+
+ let map_str = format!("{}", map);
+
+ assert!(map_str == "{1: 2, 3: 4}".to_string() || map_str == "{3: 4, 1: 2}".to_string());
+ assert_eq!(format!("{}", empty), "{}".to_string());
+ }
+
+ #[test]
+ fn test_expand() {
+ let mut m = HashMap::new();
+
+ assert_eq!(m.len(), 0);
+ assert!(m.is_empty());
+
+ let mut i = 0u;
+ let old_cap = m.table.capacity();
+ while old_cap == m.table.capacity() {
+ m.insert(i, i);
+ i += 1;
+ }
+
+ assert_eq!(m.len(), i);
+ assert!(!m.is_empty());
+ }
+
+ #[test]
+ fn test_resize_policy() {
+ let mut m = HashMap::new();
+
+ assert_eq!(m.len(), 0);
+ assert_eq!(m.table.capacity(), 0);
+ assert!(m.is_empty());
+
+ m.insert(0, 0);
+ m.remove(&0);
+ assert!(m.is_empty());
+ let initial_cap = m.table.capacity();
+ m.reserve(initial_cap * 2);
+ let cap = m.table.capacity();
+
+ assert_eq!(cap, initial_cap * 2);
+
+ let mut i = 0u;
+ for _ in range(0, cap * 3 / 4) {
+ m.insert(i, i);
+ i += 1;
+ }
+ // three quarters full
+
+ assert_eq!(m.len(), i);
+ assert_eq!(m.table.capacity(), cap);
+
+ for _ in range(0, cap / 4) {
+ m.insert(i, i);
+ i += 1;
+ }
+ // half full
+
+ let new_cap = m.table.capacity();
+ assert_eq!(new_cap, cap * 2);
+
+ for _ in range(0, cap / 2 - 1) {
+ i -= 1;
+ m.remove(&i);
+ assert_eq!(m.table.capacity(), new_cap);
+ }
+ // A little more than one quarter full.
+ // Shrinking starts as we remove more elements:
+ for _ in range(0, cap / 2 - 1) {
+ i -= 1;
+ m.remove(&i);
+ }
+
+ assert_eq!(m.len(), i);
+ assert!(!m.is_empty());
+ assert_eq!(m.table.capacity(), cap);
+ }
+
+ #[test]
+ fn test_find_equiv() {
+ let mut m = HashMap::new();
+
+ let (foo, bar, baz) = (1i,2i,3i);
+ m.insert("foo".to_string(), foo);
+ m.insert("bar".to_string(), bar);
+ m.insert("baz".to_string(), 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 = [(1i, 1i), (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));
+ }
+ }
+
+ #[test]
+ fn test_size_hint() {
+ let xs = [(1i, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+ let map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
+
+ let mut iter = map.iter();
+
+ for _ in iter.by_ref().take(3) {}
+
+ assert_eq!(iter.size_hint(), (3, Some(3)));
+ }
+
+ #[test]
+ fn test_mut_size_hint() {
+ let xs = [(1i, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+ let mut map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
+
+ let mut iter = map.iter_mut();
+
+ for _ in iter.by_ref().take(3) {}
+
+ assert_eq!(iter.size_hint(), (3, Some(3)));
+ }
+
+ #[test]
+ fn test_index() {
+ let mut map: HashMap<int, int> = HashMap::new();
+
+ map.insert(1, 2);
+ map.insert(2, 1);
+ map.insert(3, 4);
+
+ assert_eq!(map[2], 1);
+ }
+
+ #[test]
+ #[should_fail]
+ fn test_index_nonexistent() {
+ let mut map: HashMap<int, int> = HashMap::new();
+
+ map.insert(1, 2);
+ map.insert(2, 1);
+ map.insert(3, 4);
+
+ map[4];
+ }
+
+ #[test]
+ fn test_entry(){
+ let xs = [(1i, 10i), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
+
+ let mut map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
+
+ // Existing key (insert)
+ match map.entry(1) {
+ Vacant(_) => unreachable!(),
+ Occupied(mut view) => {
+ assert_eq!(view.get(), &10);
+ assert_eq!(view.set(100), 10);
+ }
+ }
+ assert_eq!(map.find(&1).unwrap(), &100);
+ assert_eq!(map.len(), 6);
+
+
+ // Existing key (update)
+ match map.entry(2) {
+ Vacant(_) => unreachable!(),
+ Occupied(mut view) => {
+ let v = view.get_mut();
+ let new_v = (*v) * 10;
+ *v = new_v;
+ }
+ }
+ assert_eq!(map.find(&2).unwrap(), &200);
+ assert_eq!(map.len(), 6);
+
+ // Existing key (take)
+ match map.entry(3) {
+ Vacant(_) => unreachable!(),
+ Occupied(view) => {
+ assert_eq!(view.take(), 30);
+ }
+ }
+ assert_eq!(map.find(&3), None);
+ assert_eq!(map.len(), 5);
+
+
+ // Inexistent key (insert)
+ match map.entry(10) {
+ Occupied(_) => unreachable!(),
+ Vacant(view) => {
+ assert_eq!(*view.set(1000), 1000);
+ }
+ }
+ assert_eq!(map.find(&10).unwrap(), &1000);
+ assert_eq!(map.len(), 6);
+ }
+}
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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
+
+mod bench;
+pub mod map;
+pub mod set;
+mod table;
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+//
+// ignore-lexer-test FIXME #15883
+
+use clone::Clone;
+use cmp::{Eq, Equiv, PartialEq};
+use core::kinds::Sized;
+use default::Default;
+use fmt::Show;
+use fmt;
+use hash::{Hash, Hasher, RandomSipHasher};
+use iter::{Iterator, FromIterator, FilterMap, Chain, Repeat, Zip, Extendable};
+use iter;
+use option::{Some, None};
+use result::{Ok, Err};
+
+use super::map::{HashMap, Entries, MoveEntries, INITIAL_CAPACITY};
+
+
+// Future Optimization (FIXME!)
+// =============================
+//
+// Iteration over zero sized values is a noop. There is no need
+// for `bucket.val` in the case of HashSet. I suppose we would need HKT
+// to get rid of it properly.
+
+/// 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.
+///
+/// # Example
+///
+/// ```
+/// use std::collections::HashSet;
+/// // Type inference lets us omit an explicit type signature (which
+/// // would be `HashSet<&str>` in this example).
+/// let mut books = HashSet::new();
+///
+/// // Add some books.
+/// books.insert("A Dance With Dragons");
+/// books.insert("To Kill a Mockingbird");
+/// books.insert("The Odyssey");
+/// books.insert("The Great Gatsby");
+///
+/// // Check for a specific one.
+/// if !books.contains(&("The Winds of Winter")) {
+/// println!("We have {} books, but The Winds of Winter ain't one.",
+/// books.len());
+/// }
+///
+/// // Remove a book.
+/// books.remove(&"The Odyssey");
+///
+/// // Iterate over everything.
+/// for book in books.iter() {
+/// println!("{}", *book);
+/// }
+/// ```
+///
+/// The easiest way to use `HashSet` with a custom type is to derive
+/// `Eq` and `Hash`. We must also derive `PartialEq`, this will in the
+/// future be implied by `Eq`.
+///
+/// ```
+/// use std::collections::HashSet;
+/// #[deriving(Hash, Eq, PartialEq, Show)]
+/// struct Viking<'a> {
+/// name: &'a str,
+/// power: uint,
+/// }
+///
+/// let mut vikings = HashSet::new();
+///
+/// vikings.insert(Viking { name: "Einar", power: 9u });
+/// vikings.insert(Viking { name: "Einar", power: 9u });
+/// vikings.insert(Viking { name: "Olaf", power: 4u });
+/// vikings.insert(Viking { name: "Harald", power: 8u });
+///
+/// // Use derived implementation to print the vikings.
+/// for x in vikings.iter() {
+/// println!("{}", x);
+/// }
+/// ```
+#[deriving(Clone)]
+pub struct HashSet<T, H = RandomSipHasher> {
+ map: HashMap<T, (), H>
+}
+
+impl<T: Hash + Eq> HashSet<T, RandomSipHasher> {
+ /// Create an empty HashSet.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ /// let mut set: HashSet<int> = HashSet::new();
+ /// ```
+ #[inline]
+ pub fn new() -> HashSet<T, RandomSipHasher> {
+ HashSet::with_capacity(INITIAL_CAPACITY)
+ }
+
+ /// Create an empty HashSet with space for at least `n` elements in
+ /// the hash table.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ /// let mut set: HashSet<int> = HashSet::with_capacity(10);
+ /// ```
+ #[inline]
+ pub fn with_capacity(capacity: uint) -> HashSet<T, RandomSipHasher> {
+ HashSet { map: HashMap::with_capacity(capacity) }
+ }
+}
+
+impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
+ /// Creates a new empty hash set which will use the given hasher to hash
+ /// keys.
+ ///
+ /// The hash set is also created with the default initial capacity.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ /// use std::hash::sip::SipHasher;
+ ///
+ /// let h = SipHasher::new();
+ /// let mut set = HashSet::with_hasher(h);
+ /// set.insert(2u);
+ /// ```
+ #[inline]
+ pub fn with_hasher(hasher: H) -> HashSet<T, H> {
+ HashSet::with_capacity_and_hasher(INITIAL_CAPACITY, hasher)
+ }
+
+ /// Create an empty HashSet with space for at least `capacity`
+ /// elements in the hash table, using `hasher` to hash the keys.
+ ///
+ /// Warning: `hasher` is normally randomly generated, and
+ /// is designed to allow `HashSet`s to be resistant to attacks that
+ /// cause many collisions and very poor performance. Setting it
+ /// manually using this function can expose a DoS attack vector.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ /// use std::hash::sip::SipHasher;
+ ///
+ /// let h = SipHasher::new();
+ /// let mut set = HashSet::with_capacity_and_hasher(10u, h);
+ /// set.insert(1i);
+ /// ```
+ #[inline]
+ pub fn with_capacity_and_hasher(capacity: uint, hasher: H) -> HashSet<T, H> {
+ HashSet { map: HashMap::with_capacity_and_hasher(capacity, hasher) }
+ }
+
+ /// Reserve space for at least `n` elements in the hash table.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ /// let mut set: HashSet<int> = HashSet::new();
+ /// set.reserve(10);
+ /// ```
+ 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.
+ ///
+ /// # Example
+ ///
+ /// This is a slightly silly example where we define the number's
+ /// parity as the equivalance class. It is important that the
+ /// values hash the same, which is why we implement `Hash`.
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ /// use std::hash::Hash;
+ /// use std::hash::sip::SipState;
+ ///
+ /// #[deriving(Eq, PartialEq)]
+ /// struct EvenOrOdd {
+ /// num: uint
+ /// };
+ ///
+ /// impl Hash for EvenOrOdd {
+ /// fn hash(&self, state: &mut SipState) {
+ /// let parity = self.num % 2;
+ /// parity.hash(state);
+ /// }
+ /// }
+ ///
+ /// impl Equiv<EvenOrOdd> for EvenOrOdd {
+ /// fn equiv(&self, other: &EvenOrOdd) -> bool {
+ /// self.num % 2 == other.num % 2
+ /// }
+ /// }
+ ///
+ /// let mut set = HashSet::new();
+ /// set.insert(EvenOrOdd { num: 3u });
+ ///
+ /// assert!(set.contains_equiv(&EvenOrOdd { num: 3u }));
+ /// assert!(set.contains_equiv(&EvenOrOdd { num: 5u }));
+ /// assert!(!set.contains_equiv(&EvenOrOdd { num: 4u }));
+ /// assert!(!set.contains_equiv(&EvenOrOdd { num: 2u }));
+ ///
+ /// ```
+ pub fn contains_equiv<Sized? Q: Hash<S> + 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.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ /// let mut set = HashSet::new();
+ /// set.insert("a");
+ /// set.insert("b");
+ ///
+ /// // Will print in an arbitrary order.
+ /// for x in set.iter() {
+ /// println!("{}", x);
+ /// }
+ /// ```
+ pub fn iter<'a>(&'a self) -> SetItems<'a, T> {
+ self.map.keys()
+ }
+
+ /// Deprecated: use `into_iter`.
+ #[deprecated = "use into_iter"]
+ pub fn move_iter(self) -> SetMoveItems<T> {
+ self.into_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.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ /// let mut set = HashSet::new();
+ /// set.insert("a".to_string());
+ /// set.insert("b".to_string());
+ ///
+ /// // Not possible to collect to a Vec<String> with a regular `.iter()`.
+ /// let v: Vec<String> = set.into_iter().collect();
+ ///
+ /// // Will print in an arbitrary order.
+ /// for x in v.iter() {
+ /// println!("{}", x);
+ /// }
+ /// ```
+ pub fn into_iter(self) -> SetMoveItems<T> {
+ self.map.into_iter().map(|(k, _)| k)
+ }
+
+ /// Visit the values representing the difference.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
+ /// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
+ ///
+ /// // Can be seen as `a - b`.
+ /// for x in a.difference(&b) {
+ /// println!("{}", x); // Print 1
+ /// }
+ ///
+ /// let diff: HashSet<int> = a.difference(&b).map(|&x| x).collect();
+ /// assert_eq!(diff, [1i].iter().map(|&x| x).collect());
+ ///
+ /// // Note that difference is not symmetric,
+ /// // and `b - a` means something else:
+ /// let diff: HashSet<int> = b.difference(&a).map(|&x| x).collect();
+ /// assert_eq!(diff, [4i].iter().map(|&x| x).collect());
+ /// ```
+ pub fn difference<'a>(&'a self, other: &'a HashSet<T, H>) -> SetAlgebraItems<'a, T, H> {
+ 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.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
+ /// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
+ ///
+ /// // Print 1, 4 in arbitrary order.
+ /// for x in a.symmetric_difference(&b) {
+ /// println!("{}", x);
+ /// }
+ ///
+ /// let diff1: HashSet<int> = a.symmetric_difference(&b).map(|&x| x).collect();
+ /// let diff2: HashSet<int> = b.symmetric_difference(&a).map(|&x| x).collect();
+ ///
+ /// assert_eq!(diff1, diff2);
+ /// assert_eq!(diff1, [1i, 4].iter().map(|&x| x).collect());
+ /// ```
+ pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet<T, H>)
+ -> Chain<SetAlgebraItems<'a, T, H>, SetAlgebraItems<'a, T, H>> {
+ self.difference(other).chain(other.difference(self))
+ }
+
+ /// Visit the values representing the intersection.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
+ /// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
+ ///
+ /// // Print 2, 3 in arbitrary order.
+ /// for x in a.intersection(&b) {
+ /// println!("{}", x);
+ /// }
+ ///
+ /// let diff: HashSet<int> = a.intersection(&b).map(|&x| x).collect();
+ /// assert_eq!(diff, [2i, 3].iter().map(|&x| x).collect());
+ /// ```
+ pub fn intersection<'a>(&'a self, other: &'a HashSet<T, H>)
+ -> SetAlgebraItems<'a, T, H> {
+ Repeat::new(other).zip(self.iter())
+ .filter_map(|(other, elt)| {
+ if other.contains(elt) { Some(elt) } else { None }
+ })
+ }
+
+ /// Visit the values representing the union.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
+ /// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
+ ///
+ /// // Print 1, 2, 3, 4 in arbitrary order.
+ /// for x in a.union(&b) {
+ /// println!("{}", x);
+ /// }
+ ///
+ /// let diff: HashSet<int> = a.union(&b).map(|&x| x).collect();
+ /// assert_eq!(diff, [1i, 2, 3, 4].iter().map(|&x| x).collect());
+ /// ```
+ pub fn union<'a>(&'a self, other: &'a HashSet<T, H>)
+ -> Chain<SetItems<'a, T>, SetAlgebraItems<'a, T, H>> {
+ self.iter().chain(other.difference(self))
+ }
+
+ /// Return the number of elements in the set
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ ///
+ /// let mut v = HashSet::new();
+ /// assert_eq!(v.len(), 0);
+ /// v.insert(1u);
+ /// assert_eq!(v.len(), 1);
+ /// ```
+ pub fn len(&self) -> uint { self.map.len() }
+
+ /// Returns true if the set contains no elements
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ ///
+ /// let mut v = HashSet::new();
+ /// assert!(v.is_empty());
+ /// v.insert(1u);
+ /// assert!(!v.is_empty());
+ /// ```
+ pub fn is_empty(&self) -> bool { self.map.len() == 0 }
+
+ /// Clears the set, removing all values.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ ///
+ /// let mut v = HashSet::new();
+ /// v.insert(1u);
+ /// v.clear();
+ /// assert!(v.is_empty());
+ /// ```
+ pub fn clear(&mut self) { self.map.clear() }
+
+ /// Returns `true` if the set contains a value.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ ///
+ /// let set: HashSet<uint> = [1, 2, 3].iter().map(|&x| x).collect();
+ /// assert_eq!(set.contains(&1), true);
+ /// assert_eq!(set.contains(&4), false);
+ /// ```
+ pub fn contains(&self, value: &T) -> bool { self.map.contains_key(value) }
+
+ /// Returns `true` if the set has no elements in common with `other`.
+ /// This is equivalent to checking for an empty intersection.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ ///
+ /// let a: HashSet<uint> = [1, 2, 3].iter().map(|&x| x).collect();
+ /// let mut b: HashSet<uint> = HashSet::new();
+ ///
+ /// assert_eq!(a.is_disjoint(&b), true);
+ /// b.insert(4);
+ /// assert_eq!(a.is_disjoint(&b), true);
+ /// b.insert(1);
+ /// assert_eq!(a.is_disjoint(&b), false);
+ /// ```
+ pub fn is_disjoint(&self, other: &HashSet<T, H>) -> bool {
+ self.iter().all(|v| !other.contains(v))
+ }
+
+ /// Returns `true` if the set is a subset of another.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ ///
+ /// let sup: HashSet<uint> = [1, 2, 3].iter().map(|&x| x).collect();
+ /// let mut set: HashSet<uint> = HashSet::new();
+ ///
+ /// assert_eq!(set.is_subset(&sup), true);
+ /// set.insert(2);
+ /// assert_eq!(set.is_subset(&sup), true);
+ /// set.insert(4);
+ /// assert_eq!(set.is_subset(&sup), false);
+ /// ```
+ pub fn is_subset(&self, other: &HashSet<T, H>) -> bool {
+ self.iter().all(|v| other.contains(v))
+ }
+
+ /// Returns `true` if the set is a superset of another.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ ///
+ /// let sub: HashSet<uint> = [1, 2].iter().map(|&x| x).collect();
+ /// let mut set: HashSet<uint> = HashSet::new();
+ ///
+ /// assert_eq!(set.is_superset(&sub), false);
+ ///
+ /// set.insert(0);
+ /// set.insert(1);
+ /// assert_eq!(set.is_superset(&sub), false);
+ ///
+ /// set.insert(2);
+ /// assert_eq!(set.is_superset(&sub), true);
+ /// ```
+ #[inline]
+ pub fn is_superset(&self, other: &HashSet<T, H>) -> bool {
+ other.is_subset(self)
+ }
+
+ /// Adds a value to the set. Returns `true` if the value was not already
+ /// present in the set.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ ///
+ /// let mut set = HashSet::new();
+ ///
+ /// assert_eq!(set.insert(2u), true);
+ /// assert_eq!(set.insert(2), false);
+ /// assert_eq!(set.len(), 1);
+ /// ```
+ pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
+
+ /// Removes a value from the set. Returns `true` if the value was
+ /// present in the set.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ ///
+ /// let mut set = HashSet::new();
+ ///
+ /// set.insert(2u);
+ /// assert_eq!(set.remove(&2), true);
+ /// assert_eq!(set.remove(&2), false);
+ /// ```
+ pub fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
+}
+
+impl<T: Eq + Hash<S>, S, H: Hasher<S>> PartialEq for HashSet<T, H> {
+ fn eq(&self, other: &HashSet<T, H>) -> bool {
+ if self.len() != other.len() { return false; }
+
+ self.iter().all(|key| other.contains(key))
+ }
+}
+
+impl<T: Eq + Hash<S>, S, H: Hasher<S>> Eq for HashSet<T, H> {}
+
+impl<T: Eq + Hash<S> + fmt::Show, S, H: Hasher<S>> fmt::Show for HashSet<T, H> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ try!(write!(f, "{{"));
+
+ for (i, x) in self.iter().enumerate() {
+ if i != 0 { try!(write!(f, ", ")); }
+ try!(write!(f, "{}", *x));
+ }
+
+ write!(f, "}}")
+ }
+}
+
+impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> FromIterator<T> for HashSet<T, H> {
+ fn from_iter<I: Iterator<T>>(iter: I) -> HashSet<T, H> {
+ let (lower, _) = iter.size_hint();
+ let mut set = HashSet::with_capacity_and_hasher(lower, Default::default());
+ set.extend(iter);
+ set
+ }
+}
+
+impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> Extendable<T> for HashSet<T, H> {
+ fn extend<I: Iterator<T>>(&mut self, mut iter: I) {
+ for k in iter {
+ self.insert(k);
+ }
+ }
+}
+
+impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> Default for HashSet<T, H> {
+ fn default() -> HashSet<T, H> {
+ HashSet::with_hasher(Default::default())
+ }
+}
+
+/// HashSet iterator
+pub type SetItems<'a, K> =
+ iter::Map<'static, (&'a K, &'a ()), &'a K, Entries<'a, K, ()>>;
+
+/// HashSet move iterator
+pub type SetMoveItems<K> =
+ iter::Map<'static, (K, ()), K, MoveEntries<K, ()>>;
+
+// `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, H> =
+ FilterMap<'static, (&'a HashSet<T, H>, &'a T), &'a T,
+ Zip<Repeat<&'a HashSet<T, H>>, SetItems<'a, T>>>;
+
+#[cfg(test)]
+mod test_set {
+ use prelude::*;
+
+ use super::HashSet;
+ use slice::ImmutablePartialEqSlice;
+
+ #[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(5i));
+ assert!(ys.insert(11i));
+ assert!(xs.is_disjoint(&ys));
+ assert!(ys.is_disjoint(&xs));
+ assert!(xs.insert(7));
+ assert!(xs.insert(19));
+ assert!(xs.insert(4));
+ assert!(ys.insert(2));
+ assert!(ys.insert(-11));
+ assert!(xs.is_disjoint(&ys));
+ assert!(ys.is_disjoint(&xs));
+ assert!(ys.insert(7));
+ assert!(!xs.is_disjoint(&ys));
+ assert!(!ys.is_disjoint(&xs));
+ }
+
+ #[test]
+ fn test_subset_and_superset() {
+ let mut a = HashSet::new();
+ assert!(a.insert(0i));
+ assert!(a.insert(5));
+ assert!(a.insert(11));
+ assert!(a.insert(7));
+
+ let mut b = HashSet::new();
+ assert!(b.insert(0i));
+ assert!(b.insert(7));
+ assert!(b.insert(19));
+ assert!(b.insert(250));
+ assert!(b.insert(11));
+ assert!(b.insert(200));
+
+ assert!(!a.is_subset(&b));
+ assert!(!a.is_superset(&b));
+ assert!(!b.is_subset(&a));
+ assert!(!b.is_superset(&a));
+
+ assert!(b.insert(5));
+
+ assert!(a.is_subset(&b));
+ assert!(!a.is_superset(&b));
+ assert!(!b.is_subset(&a));
+ assert!(b.is_superset(&a));
+ }
+
+ #[test]
+ fn test_iterate() {
+ let mut a = HashSet::new();
+ for i in range(0u, 32) {
+ assert!(a.insert(i));
+ }
+ let mut observed: u32 = 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(11i));
+ 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(2i));
+ 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(1i));
+ assert!(a.insert(3));
+ assert!(a.insert(5));
+ assert!(a.insert(9));
+ assert!(a.insert(11));
+
+ assert!(b.insert(3i));
+ 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(1i));
+ assert!(a.insert(3));
+ assert!(a.insert(5));
+ assert!(a.insert(9));
+ assert!(a.insert(11));
+
+ assert!(b.insert(-2i));
+ 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(1i));
+ 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(-2i));
+ 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 = [1i, 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.into_iter().collect::<Vec<char>>();
+ assert!(['a', 'b'] == v.as_slice() || ['b', 'a'] == v.as_slice());
+ }
+
+ #[test]
+ fn test_eq() {
+ // These constants once happened to expose a bug in insert().
+ // I'm keeping them around to prevent a regression.
+ let mut s1 = HashSet::new();
+
+ s1.insert(1i);
+ s1.insert(2);
+ s1.insert(3);
+
+ let mut s2 = HashSet::new();
+
+ s2.insert(1i);
+ 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(1i);
+ set.insert(2);
+
+ let set_str = format!("{}", set);
+
+ assert!(set_str == "{1, 2}".to_string() || set_str == "{2, 1}".to_string());
+ assert_eq!(format!("{}", empty), "{}".to_string());
+ }
+}
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+//
+// ignore-lexer-test FIXME #15883
+
+use clone::Clone;
+use cmp;
+use hash::{Hash, Hasher};
+use iter::{Iterator, count};
+use kinds::{Sized, marker};
+use mem::{min_align_of, size_of};
+use mem;
+use num::{CheckedAdd, CheckedMul, is_power_of_two};
+use ops::{Deref, DerefMut, Drop};
+use option::{Some, None, Option};
+use ptr::{RawPtr, copy_nonoverlapping_memory, zero_memory};
+use ptr;
+use rt::heap::{allocate, deallocate};
+
+const EMPTY_BUCKET: u64 = 0u64;
+
+/// The raw hashtable, providing safe-ish access to the unzipped and highly
+/// optimized arrays of hashes, keys, and values.
+///
+/// This design uses less memory and is a lot faster than the naive
+/// `Vec<Option<u64, K, V>>`, because we don't pay for the overhead of an
+/// option on every element, and we get a generally more cache-aware design.
+///
+/// Essential invariants of this structure:
+///
+/// - if t.hashes[i] == EMPTY_BUCKET, then `Bucket::at_index(&t, i).raw`
+/// points to 'undefined' contents. Don't read from it. This invariant is
+/// enforced outside this module with the `EmptyBucket`, `FullBucket`,
+/// and `SafeHash` types.
+///
+/// - An `EmptyBucket` is only constructed at an index with
+/// a hash of EMPTY_BUCKET.
+///
+/// - A `FullBucket` is only constructed at an index with a
+/// non-EMPTY_BUCKET hash.
+///
+/// - A `SafeHash` is only constructed for non-`EMPTY_BUCKET` hash. We get
+/// around hashes of zero by changing them to 0x8000_0000_0000_0000,
+/// which will likely map to the same bucket, while not being confused
+/// with "empty".
+///
+/// - All three "arrays represented by pointers" are the same length:
+/// `capacity`. This is set at creation and never changes. The arrays
+/// are unzipped to save space (we don't have to pay for the padding
+/// between odd sized elements, such as in a map from u64 to u8), and
+/// be more cache aware (scanning through 8 hashes brings in at most
+/// 2 cache lines, since they're all right beside each other).
+///
+/// You can kind of think of this module/data structure as a safe wrapper
+/// around just the "table" part of the hashtable. It enforces some
+/// invariants at the type level and employs some performance trickery,
+/// but in general is just a tricked out `Vec<Option<u64, K, V>>`.
+#[unsafe_no_drop_flag]
+pub struct RawTable<K, V> {
+ capacity: uint,
+ size: uint,
+ hashes: *mut u64,
+ // Because K/V do not appear directly in any of the types in the struct,
+ // inform rustc that in fact instances of K and V are reachable from here.
+ marker: marker::CovariantType<(K,V)>,
+}
+
+struct RawBucket<K, V> {
+ hash: *mut u64,
+ key: *mut K,
+ val: *mut V
+}
+
+pub struct Bucket<K, V, M> {
+ raw: RawBucket<K, V>,
+ idx: uint,
+ table: M
+}
+
+pub struct EmptyBucket<K, V, M> {
+ raw: RawBucket<K, V>,
+ idx: uint,
+ table: M
+}
+
+pub struct FullBucket<K, V, M> {
+ raw: RawBucket<K, V>,
+ idx: uint,
+ table: M
+}
+
+pub type EmptyBucketImm<'table, K, V> = EmptyBucket<K, V, &'table RawTable<K, V>>;
+pub type FullBucketImm<'table, K, V> = FullBucket<K, V, &'table RawTable<K, V>>;
+
+pub type EmptyBucketMut<'table, K, V> = EmptyBucket<K, V, &'table mut RawTable<K, V>>;
+pub type FullBucketMut<'table, K, V> = FullBucket<K, V, &'table mut RawTable<K, V>>;
+
+pub enum BucketState<K, V, M> {
+ Empty(EmptyBucket<K, V, M>),
+ Full(FullBucket<K, V, M>),
+}
+
+// A GapThenFull encapsulates the state of two consecutive buckets at once.
+// The first bucket, called the gap, is known to be empty.
+// The second bucket is full.
+struct GapThenFull<K, V, M> {
+ gap: EmptyBucket<K, V, ()>,
+ full: FullBucket<K, V, M>,
+}
+
+/// A hash that is not zero, since we use a hash of zero to represent empty
+/// buckets.
+#[deriving(PartialEq)]
+pub struct SafeHash {
+ hash: u64,
+}
+
+impl SafeHash {
+ /// Peek at the hash value, which is guaranteed to be non-zero.
+ #[inline(always)]
+ pub fn inspect(&self) -> u64 { self.hash }
+}
+
+/// We need to remove hashes of 0. That's reserved for empty buckets.
+/// This function wraps up `hash_keyed` to be the only way outside this
+/// module to generate a SafeHash.
+pub fn make_hash<Sized? T: Hash<S>, S, H: Hasher<S>>(hasher: &H, t: &T) -> SafeHash {
+ match hasher.hash(t) {
+ // This constant is exceedingly likely to hash to the same
+ // bucket, but it won't be counted as empty! Just so we can maintain
+ // our precious uniform distribution of initial indexes.
+ EMPTY_BUCKET => SafeHash { hash: 0x8000_0000_0000_0000 },
+ h => SafeHash { hash: h },
+ }
+}
+
+// `replace` casts a `*u64` to a `*SafeHash`. Since we statically
+// ensure that a `FullBucket` points to an index with a non-zero hash,
+// and a `SafeHash` is just a `u64` with a different name, this is
+// safe.
+//
+// This test ensures that a `SafeHash` really IS the same size as a
+// `u64`. If you need to change the size of `SafeHash` (and
+// consequently made this test fail), `replace` needs to be
+// modified to no longer assume this.
+#[test]
+fn can_alias_safehash_as_u64() {
+ assert_eq!(size_of::<SafeHash>(), size_of::<u64>())
+}
+
+impl<K, V> RawBucket<K, V> {
+ unsafe fn offset(self, count: int) -> RawBucket<K, V> {
+ RawBucket {
+ hash: self.hash.offset(count),
+ key: self.key.offset(count),
+ val: self.val.offset(count),
+ }
+ }
+}
+
+// For parameterizing over mutability.
+impl<'t, K, V> Deref<RawTable<K, V>> for &'t RawTable<K, V> {
+ fn deref(&self) -> &RawTable<K, V> {
+ &**self
+ }
+}
+
+impl<'t, K, V> Deref<RawTable<K, V>> for &'t mut RawTable<K, V> {
+ fn deref(&self) -> &RawTable<K,V> {
+ &**self
+ }
+}
+
+impl<'t, K, V> DerefMut<RawTable<K, V>> for &'t mut RawTable<K, V> {
+ fn deref_mut(&mut self) -> &mut RawTable<K,V> {
+ &mut **self
+ }
+}
+
+// Buckets hold references to the table.
+impl<K, V, M> FullBucket<K, V, M> {
+ /// Borrow a reference to the table.
+ pub fn table(&self) -> &M {
+ &self.table
+ }
+ /// Move out the reference to the table.
+ pub fn into_table(self) -> M {
+ self.table
+ }
+ /// Get the raw index.
+ pub fn index(&self) -> uint {
+ self.idx
+ }
+}
+
+impl<K, V, M> EmptyBucket<K, V, M> {
+ /// Borrow a reference to the table.
+ pub fn table(&self) -> &M {
+ &self.table
+ }
+ /// Move out the reference to the table.
+ pub fn into_table(self) -> M {
+ self.table
+ }
+}
+
+impl<K, V, M> Bucket<K, V, M> {
+ /// Move out the reference to the table.
+ pub fn into_table(self) -> M {
+ self.table
+ }
+ /// Get the raw index.
+ pub fn index(&self) -> uint {
+ self.idx
+ }
+}
+
+impl<K, V, M: Deref<RawTable<K, V>>> Bucket<K, V, M> {
+ pub fn new(table: M, hash: &SafeHash) -> Bucket<K, V, M> {
+ Bucket::at_index(table, hash.inspect() as uint)
+ }
+
+ pub fn at_index(table: M, ib_index: uint) -> Bucket<K, V, M> {
+ let ib_index = ib_index & (table.capacity() - 1);
+ Bucket {
+ raw: unsafe {
+ table.first_bucket_raw().offset(ib_index as int)
+ },
+ idx: ib_index,
+ table: table
+ }
+ }
+
+ pub fn first(table: M) -> Bucket<K, V, M> {
+ Bucket {
+ raw: table.first_bucket_raw(),
+ idx: 0,
+ table: table
+ }
+ }
+
+ /// Reads a bucket at a given index, returning an enum indicating whether
+ /// it's initialized or not. You need to match on this enum to get
+ /// the appropriate types to call most of the other functions in
+ /// this module.
+ pub fn peek(self) -> BucketState<K, V, M> {
+ match unsafe { *self.raw.hash } {
+ EMPTY_BUCKET =>
+ Empty(EmptyBucket {
+ raw: self.raw,
+ idx: self.idx,
+ table: self.table
+ }),
+ _ =>
+ Full(FullBucket {
+ raw: self.raw,
+ idx: self.idx,
+ table: self.table
+ })
+ }
+ }
+
+ /// Modifies the bucket pointer in place to make it point to the next slot.
+ pub fn next(&mut self) {
+ // Branchless bucket iteration step.
+ // As we reach the end of the table...
+ // We take the current idx: 0111111b
+ // Xor it by its increment: ^ 1000000b
+ // ------------
+ // 1111111b
+ // Then AND with the capacity: & 1000000b
+ // ------------
+ // to get the backwards offset: 1000000b
+ // ... and it's zero at all other times.
+ let maybe_wraparound_dist = (self.idx ^ (self.idx + 1)) & self.table.capacity();
+ // Finally, we obtain the offset 1 or the offset -cap + 1.
+ let dist = 1i - (maybe_wraparound_dist as int);
+
+ self.idx += 1;
+
+ unsafe {
+ self.raw = self.raw.offset(dist);
+ }
+ }
+}
+
+impl<K, V, M: Deref<RawTable<K, V>>> EmptyBucket<K, V, M> {
+ #[inline]
+ pub fn next(self) -> Bucket<K, V, M> {
+ let mut bucket = self.into_bucket();
+ bucket.next();
+ bucket
+ }
+
+ #[inline]
+ pub fn into_bucket(self) -> Bucket<K, V, M> {
+ Bucket {
+ raw: self.raw,
+ idx: self.idx,
+ table: self.table
+ }
+ }
+
+ pub fn gap_peek(self) -> Option<GapThenFull<K, V, M>> {
+ let gap = EmptyBucket {
+ raw: self.raw,
+ idx: self.idx,
+ table: ()
+ };
+
+ match self.next().peek() {
+ Full(bucket) => {
+ Some(GapThenFull {
+ gap: gap,
+ full: bucket
+ })
+ }
+ Empty(..) => None
+ }
+ }
+}
+
+impl<K, V, M: DerefMut<RawTable<K, V>>> EmptyBucket<K, V, M> {
+ /// Puts given key and value pair, along with the key's hash,
+ /// into this bucket in the hashtable. Note how `self` is 'moved' into
+ /// this function, because this slot will no longer be empty when
+ /// we return! A `FullBucket` is returned for later use, pointing to
+ /// the newly-filled slot in the hashtable.
+ ///
+ /// Use `make_hash` to construct a `SafeHash` to pass to this function.
+ pub fn put(mut self, hash: SafeHash, key: K, value: V)
+ -> FullBucket<K, V, M> {
+ unsafe {
+ *self.raw.hash = hash.inspect();
+ ptr::write(self.raw.key, key);
+ ptr::write(self.raw.val, value);
+ }
+
+ self.table.size += 1;
+
+ FullBucket { raw: self.raw, idx: self.idx, table: self.table }
+ }
+}
+
+impl<K, V, M: Deref<RawTable<K, V>>> FullBucket<K, V, M> {
+ #[inline]
+ pub fn next(self) -> Bucket<K, V, M> {
+ let mut bucket = self.into_bucket();
+ bucket.next();
+ bucket
+ }
+
+ #[inline]
+ pub fn into_bucket(self) -> Bucket<K, V, M> {
+ Bucket {
+ raw: self.raw,
+ idx: self.idx,
+ table: self.table
+ }
+ }
+
+ /// Get the distance between this bucket and the 'ideal' location
+ /// as determined by the key's hash stored in it.
+ ///
+ /// In the cited blog posts above, this is called the "distance to
+ /// initial bucket", or DIB. Also known as "probe count".
+ pub fn distance(&self) -> uint {
+ // Calculates the distance one has to travel when going from
+ // `hash mod capacity` onwards to `idx mod capacity`, wrapping around
+ // if the destination is not reached before the end of the table.
+ (self.idx - self.hash().inspect() as uint) & (self.table.capacity() - 1)
+ }
+
+ #[inline]
+ pub fn hash(&self) -> SafeHash {
+ unsafe {
+ SafeHash {
+ hash: *self.raw.hash
+ }
+ }
+ }
+
+ /// Gets references to the key and value at a given index.
+ pub fn read(&self) -> (&K, &V) {
+ unsafe {
+ (&*self.raw.key,
+ &*self.raw.val)
+ }
+ }
+}
+
+impl<K, V, M: DerefMut<RawTable<K, V>>> FullBucket<K, V, M> {
+ /// Removes this bucket's key and value from the hashtable.
+ ///
+ /// This works similarly to `put`, building an `EmptyBucket` out of the
+ /// taken bucket.
+ pub fn take(mut self) -> (EmptyBucket<K, V, M>, K, V) {
+ let key = self.raw.key as *const K;
+ let val = self.raw.val as *const V;
+
+ self.table.size -= 1;
+
+ unsafe {
+ *self.raw.hash = EMPTY_BUCKET;
+ (
+ EmptyBucket {
+ raw: self.raw,
+ idx: self.idx,
+ table: self.table
+ },
+ ptr::read(key),
+ ptr::read(val)
+ )
+ }
+ }
+
+ pub fn replace(&mut self, h: SafeHash, k: K, v: V) -> (SafeHash, K, V) {
+ unsafe {
+ let old_hash = ptr::replace(self.raw.hash as *mut SafeHash, h);
+ let old_key = ptr::replace(self.raw.key, k);
+ let old_val = ptr::replace(self.raw.val, v);
+
+ (old_hash, old_key, old_val)
+ }
+ }
+
+ /// Gets mutable references to the key and value at a given index.
+ pub fn read_mut(&mut self) -> (&mut K, &mut V) {
+ unsafe {
+ (&mut *self.raw.key,
+ &mut *self.raw.val)
+ }
+ }
+}
+
+impl<'t, K, V, M: Deref<RawTable<K, V>> + 't> FullBucket<K, V, M> {
+ /// Exchange a bucket state for immutable references into the table.
+ /// Because the underlying reference to the table is also consumed,
+ /// no further changes to the structure of the table are possible;
+ /// in exchange for this, the returned references have a longer lifetime
+ /// than the references returned by `read()`.
+ pub fn into_refs(self) -> (&'t K, &'t V) {
+ unsafe {
+ (&*self.raw.key,
+ &*self.raw.val)
+ }
+ }
+}
+
+impl<'t, K, V, M: DerefMut<RawTable<K, V>> + 't> FullBucket<K, V, M> {
+ /// This works similarly to `into_refs`, exchanging a bucket state
+ /// for mutable references into the table.
+ pub fn into_mut_refs(self) -> (&'t mut K, &'t mut V) {
+ unsafe {
+ (&mut *self.raw.key,
+ &mut *self.raw.val)
+ }
+ }
+}
+
+impl<K, V, M> BucketState<K, V, M> {
+ // For convenience.
+ pub fn expect_full(self) -> FullBucket<K, V, M> {
+ match self {
+ Full(full) => full,
+ Empty(..) => panic!("Expected full bucket")
+ }
+ }
+}
+
+impl<K, V, M: Deref<RawTable<K, V>>> GapThenFull<K, V, M> {
+ #[inline]
+ pub fn full(&self) -> &FullBucket<K, V, M> {
+ &self.full
+ }
+
+ pub fn shift(mut self) -> Option<GapThenFull<K, V, M>> {
+ unsafe {
+ *self.gap.raw.hash = mem::replace(&mut *self.full.raw.hash, EMPTY_BUCKET);
+ copy_nonoverlapping_memory(self.gap.raw.key, self.full.raw.key as *const K, 1);
+ copy_nonoverlapping_memory(self.gap.raw.val, self.full.raw.val as *const V, 1);
+ }
+
+ let FullBucket { raw: prev_raw, idx: prev_idx, .. } = self.full;
+
+ match self.full.next().peek() {
+ Full(bucket) => {
+ self.gap.raw = prev_raw;
+ self.gap.idx = prev_idx;
+
+ self.full = bucket;
+
+ Some(self)
+ }
+ Empty(..) => None
+ }
+ }
+}
+
+
+/// Rounds up to a multiple of a power of two. Returns the closest multiple
+/// of `target_alignment` that is higher or equal to `unrounded`.
+///
+/// # Failure
+///
+/// Fails if `target_alignment` is not a power of two.
+fn round_up_to_next(unrounded: uint, target_alignment: uint) -> uint {
+ assert!(is_power_of_two(target_alignment));
+ (unrounded + target_alignment - 1) & !(target_alignment - 1)
+}
+
+#[test]
+fn test_rounding() {
+ assert_eq!(round_up_to_next(0, 4), 0);
+ assert_eq!(round_up_to_next(1, 4), 4);
+ assert_eq!(round_up_to_next(2, 4), 4);
+ assert_eq!(round_up_to_next(3, 4), 4);
+ assert_eq!(round_up_to_next(4, 4), 4);
+ assert_eq!(round_up_to_next(5, 4), 8);
+}
+
+// Returns a tuple of (key_offset, val_offset),
+// from the start of a mallocated array.
+fn calculate_offsets(hashes_size: uint,
+ keys_size: uint, keys_align: uint,
+ vals_align: uint)
+ -> (uint, uint) {
+ let keys_offset = round_up_to_next(hashes_size, keys_align);
+ let end_of_keys = keys_offset + keys_size;
+
+ let vals_offset = round_up_to_next(end_of_keys, vals_align);
+
+ (keys_offset, vals_offset)
+}
+
+// Returns a tuple of (minimum required malloc alignment, hash_offset,
+// array_size), from the start of a mallocated array.
+fn calculate_allocation(hash_size: uint, hash_align: uint,
+ keys_size: uint, keys_align: uint,
+ vals_size: uint, vals_align: uint)
+ -> (uint, uint, uint) {
+ let hash_offset = 0;
+ let (_, vals_offset) = calculate_offsets(hash_size,
+ keys_size, keys_align,
+ vals_align);
+ let end_of_vals = vals_offset + vals_size;
+
+ let min_align = cmp::max(hash_align, cmp::max(keys_align, vals_align));
+
+ (min_align, hash_offset, end_of_vals)
+}
+
+#[test]
+fn test_offset_calculation() {
+ assert_eq!(calculate_allocation(128, 8, 15, 1, 4, 4), (8, 0, 148));
+ assert_eq!(calculate_allocation(3, 1, 2, 1, 1, 1), (1, 0, 6));
+ assert_eq!(calculate_allocation(6, 2, 12, 4, 24, 8), (8, 0, 48));
+ assert_eq!(calculate_offsets(128, 15, 1, 4), (128, 144));
+ assert_eq!(calculate_offsets(3, 2, 1, 1), (3, 5));
+ assert_eq!(calculate_offsets(6, 12, 4, 8), (8, 24));
+}
+
+impl<K, V> RawTable<K, V> {
+ /// Does not initialize the buckets. The caller should ensure they,
+ /// at the very least, set every hash to EMPTY_BUCKET.
+ unsafe fn new_uninitialized(capacity: uint) -> RawTable<K, V> {
+ if capacity == 0 {
+ return RawTable {
+ size: 0,
+ capacity: 0,
+ hashes: 0 as *mut u64,
+ marker: marker::CovariantType,
+ };
+ }
+ // No need for `checked_mul` before a more restrictive check performed
+ // later in this method.
+ let hashes_size = capacity * size_of::<u64>();
+ let keys_size = capacity * size_of::< K >();
+ let vals_size = capacity * size_of::< V >();
+
+ // Allocating hashmaps is a little tricky. We need to allocate three
+ // arrays, but since we know their sizes and alignments up front,
+ // we just allocate a single array, and then have the subarrays
+ // point into it.
+ //
+ // This is great in theory, but in practice getting the alignment
+ // right is a little subtle. Therefore, calculating offsets has been
+ // factored out into a different function.
+ let (malloc_alignment, hash_offset, size) =
+ calculate_allocation(
+ hashes_size, min_align_of::<u64>(),
+ keys_size, min_align_of::< K >(),
+ vals_size, min_align_of::< V >());
+
+ // One check for overflow that covers calculation and rounding of size.
+ let size_of_bucket = size_of::<u64>().checked_add(&size_of::<K>()).unwrap()
+ .checked_add(&size_of::<V>()).unwrap();
+ assert!(size >= capacity.checked_mul(&size_of_bucket)
+ .expect("capacity overflow"),
+ "capacity overflow");
+
+ let buffer = allocate(size, malloc_alignment);
+ if buffer.is_null() { ::alloc::oom() }
+
+ let hashes = buffer.offset(hash_offset as int) as *mut u64;
+
+ RawTable {
+ capacity: capacity,
+ size: 0,
+ hashes: hashes,
+ marker: marker::CovariantType,
+ }
+ }
+
+ fn first_bucket_raw(&self) -> RawBucket<K, V> {
+ let hashes_size = self.capacity * size_of::<u64>();
+ let keys_size = self.capacity * size_of::<K>();
+
+ let buffer = self.hashes as *mut u8;
+ let (keys_offset, vals_offset) = calculate_offsets(hashes_size,
+ keys_size, min_align_of::<K>(),
+ min_align_of::<V>());
+
+ unsafe {
+ RawBucket {
+ hash: self.hashes,
+ key: buffer.offset(keys_offset as int) as *mut K,
+ val: buffer.offset(vals_offset as int) as *mut V
+ }
+ }
+ }
+
+ /// Creates a new raw table from a given capacity. All buckets are
+ /// initially empty.
+ #[allow(experimental)]
+ pub fn new(capacity: uint) -> RawTable<K, V> {
+ unsafe {
+ let ret = RawTable::new_uninitialized(capacity);
+ zero_memory(ret.hashes, capacity);
+ ret
+ }
+ }
+
+ /// The hashtable's capacity, similar to a vector's.
+ pub fn capacity(&self) -> uint {
+ self.capacity
+ }
+
+ /// The number of elements ever `put` in the hashtable, minus the number
+ /// of elements ever `take`n.
+ pub fn size(&self) -> uint {
+ self.size
+ }
+
+ fn raw_buckets(&self) -> RawBuckets<K, V> {
+ RawBuckets {
+ raw: self.first_bucket_raw(),
+ hashes_end: unsafe {
+ self.hashes.offset(self.capacity as int)
+ },
+ marker: marker::ContravariantLifetime,
+ }
+ }
+
+ pub fn iter(&self) -> Entries<K, V> {
+ Entries {
+ iter: self.raw_buckets(),
+ elems_left: self.size(),
+ }
+ }
+
+ pub fn iter_mut(&mut self) -> MutEntries<K, V> {
+ MutEntries {
+ iter: self.raw_buckets(),
+ elems_left: self.size(),
+ }
+ }
+
+ pub fn into_iter(self) -> MoveEntries<K, V> {
+ let RawBuckets { raw, hashes_end, .. } = self.raw_buckets();
+ // Replace the marker regardless of lifetime bounds on parameters.
+ MoveEntries {
+ iter: RawBuckets {
+ raw: raw,
+ hashes_end: hashes_end,
+ marker: marker::ContravariantLifetime,
+ },
+ table: self,
+ }
+ }
+
+ /// Returns an iterator that copies out each entry. Used while the table
+ /// is being dropped.
+ unsafe fn rev_move_buckets(&mut self) -> RevMoveBuckets<K, V> {
+ let raw_bucket = self.first_bucket_raw();
+ RevMoveBuckets {
+ raw: raw_bucket.offset(self.capacity as int),
+ hashes_end: raw_bucket.hash,
+ elems_left: self.size,
+ marker: marker::ContravariantLifetime,
+ }
+ }
+}
+
+/// A raw iterator. The basis for some other iterators in this module. Although
+/// this interface is safe, it's not used outside this module.
+struct RawBuckets<'a, K, V> {
+ raw: RawBucket<K, V>,
+ hashes_end: *mut u64,
+ marker: marker::ContravariantLifetime<'a>,
+}
+
+impl<'a, K, V> Iterator<RawBucket<K, V>> for RawBuckets<'a, K, V> {
+ fn next(&mut self) -> Option<RawBucket<K, V>> {
+ while self.raw.hash != self.hashes_end {
+ unsafe {
+ // We are swapping out the pointer to a bucket and replacing
+ // it with the pointer to the next one.
+ let prev = ptr::replace(&mut self.raw, self.raw.offset(1));
+ if *prev.hash != EMPTY_BUCKET {
+ return Some(prev);
+ }
+ }
+ }
+
+ None
+ }
+}
+
+/// An iterator that moves out buckets in reverse order. It leaves the table
+/// in an an inconsistent state and should only be used for dropping
+/// the table's remaining entries. It's used in the implementation of Drop.
+struct RevMoveBuckets<'a, K, V> {
+ raw: RawBucket<K, V>,
+ hashes_end: *mut u64,
+ elems_left: uint,
+ marker: marker::ContravariantLifetime<'a>,
+}
+
+impl<'a, K, V> Iterator<(K, V)> for RevMoveBuckets<'a, K, V> {
+ fn next(&mut self) -> Option<(K, V)> {
+ if self.elems_left == 0 {
+ return None;
+ }
+
+ loop {
+ debug_assert!(self.raw.hash != self.hashes_end);
+
+ unsafe {
+ self.raw = self.raw.offset(-1);
+
+ if *self.raw.hash != EMPTY_BUCKET {
+ self.elems_left -= 1;
+ return Some((
+ ptr::read(self.raw.key as *const K),
+ ptr::read(self.raw.val as *const V)
+ ));
+ }
+ }
+ }
+ }
+}
+
+/// Iterator over shared references to entries in a table.
+pub struct Entries<'a, K: 'a, V: 'a> {
+ iter: RawBuckets<'a, K, V>,
+ elems_left: uint,
+}
+
+/// Iterator over mutable references to entries in a table.
+pub struct MutEntries<'a, K: 'a, V: 'a> {
+ iter: RawBuckets<'a, K, V>,
+ elems_left: uint,
+}
+
+/// Iterator over the entries in a table, consuming the table.
+pub struct MoveEntries<K, V> {
+ table: RawTable<K, V>,
+ iter: RawBuckets<'static, K, V>
+}
+
+impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
+ fn next(&mut self) -> Option<(&'a K, &'a V)> {
+ self.iter.next().map(|bucket| {
+ self.elems_left -= 1;
+ unsafe {
+ (&*bucket.key,
+ &*bucket.val)
+ }
+ })
+ }
+
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ (self.elems_left, Some(self.elems_left))
+ }
+}
+
+impl<'a, K, V> Iterator<(&'a K, &'a mut V)> for MutEntries<'a, K, V> {
+ fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
+ self.iter.next().map(|bucket| {
+ self.elems_left -= 1;
+ unsafe {
+ (&*bucket.key,
+ &mut *bucket.val)
+ }
+ })
+ }
+
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ (self.elems_left, Some(self.elems_left))
+ }
+}
+
+impl<K, V> Iterator<(SafeHash, K, V)> for MoveEntries<K, V> {
+ fn next(&mut self) -> Option<(SafeHash, K, V)> {
+ self.iter.next().map(|bucket| {
+ self.table.size -= 1;
+ unsafe {
+ (
+ SafeHash {
+ hash: *bucket.hash,
+ },
+ ptr::read(bucket.key as *const K),
+ ptr::read(bucket.val as *const V)
+ )
+ }
+ })
+ }
+
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ let size = self.table.size();
+ (size, Some(size))
+ }
+}
+
+impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
+ fn clone(&self) -> RawTable<K, V> {
+ unsafe {
+ let mut new_ht = RawTable::new_uninitialized(self.capacity());
+
+ {
+ let cap = self.capacity();
+ let mut new_buckets = Bucket::first(&mut new_ht);
+ let mut buckets = Bucket::first(self);
+ while buckets.index() != cap {
+ match buckets.peek() {
+ Full(full) => {
+ let (h, k, v) = {
+ let (k, v) = full.read();
+ (full.hash(), k.clone(), v.clone())
+ };
+ *new_buckets.raw.hash = h.inspect();
+ ptr::write(new_buckets.raw.key, k);
+ ptr::write(new_buckets.raw.val, v);
+ }
+ Empty(..) => {
+ *new_buckets.raw.hash = EMPTY_BUCKET;
+ }
+ }
+ new_buckets.next();
+ buckets.next();
+ }
+ };
+
+ new_ht.size = self.size();
+
+ new_ht
+ }
+ }
+}
+
+#[unsafe_destructor]
+impl<K, V> Drop for RawTable<K, V> {
+ fn drop(&mut self) {
+ if self.hashes.is_null() {
+ return;
+ }
+ // This is done in reverse because we've likely partially taken
+ // some elements out with `.into_iter()` from the front.
+ // Check if the size is 0, so we don't do a useless scan when
+ // dropping empty tables such as on resize.
+ // Also avoid double drop of elements that have been already moved out.
+ unsafe {
+ for _ in self.rev_move_buckets() {}
+ }
+
+ let hashes_size = self.capacity * size_of::<u64>();
+ let keys_size = self.capacity * size_of::<K>();
+ let vals_size = self.capacity * size_of::<V>();
+ let (align, _, size) = calculate_allocation(hashes_size, min_align_of::<u64>(),
+ keys_size, min_align_of::<K>(),
+ vals_size, min_align_of::<V>());
+
+ unsafe {
+ deallocate(self.hashes as *mut u8, size, align);
+ // Remember how everything was allocated out of one buffer
+ // during initialization? We only need one call to free here.
+ }
+ }
+}
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <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.
-
-#![cfg(test)]
-
-extern crate test;
-use prelude::*;
-
-use self::test::Bencher;
-use iter::{range_inclusive};
-
-#[bench]
-fn new_drop(b : &mut Bencher) {
- use super::HashMap;
-
- b.iter(|| {
- let m : HashMap<int, int> = HashMap::new();
- assert_eq!(m.len(), 0);
- })
-}
-
-#[bench]
-fn new_insert_drop(b : &mut Bencher) {
- use super::HashMap;
-
- b.iter(|| {
- let mut m = HashMap::new();
- m.insert(0i, 0i);
- assert_eq!(m.len(), 1);
- })
-}
-
-#[bench]
-fn grow_by_insertion(b: &mut Bencher) {
- use super::HashMap;
-
- let mut m = HashMap::new();
-
- for i in range_inclusive(1i, 1000) {
- m.insert(i, i);
- }
-
- let mut k = 1001;
-
- b.iter(|| {
- m.insert(k, k);
- k += 1;
- });
-}
-
-#[bench]
-fn find_existing(b: &mut Bencher) {
- use super::HashMap;
-
- let mut m = HashMap::new();
-
- for i in range_inclusive(1i, 1000) {
- m.insert(i, i);
- }
-
- b.iter(|| {
- for i in range_inclusive(1i, 1000) {
- m.contains_key(&i);
- }
- });
-}
-
-#[bench]
-fn find_nonexisting(b: &mut Bencher) {
- use super::HashMap;
-
- let mut m = HashMap::new();
-
- for i in range_inclusive(1i, 1000) {
- m.insert(i, i);
- }
-
- b.iter(|| {
- for i in range_inclusive(1001i, 2000) {
- m.contains_key(&i);
- }
- });
-}
-
-#[bench]
-fn hashmap_as_queue(b: &mut Bencher) {
- use super::HashMap;
-
- let mut m = HashMap::new();
-
- for i in range_inclusive(1i, 1000) {
- m.insert(i, i);
- }
-
- let mut k = 1i;
-
- b.iter(|| {
- m.pop(&k);
- m.insert(k + 1000, k + 1000);
- k += 1;
- });
-}
-
-#[bench]
-fn find_pop_insert(b: &mut Bencher) {
- use super::HashMap;
-
- let mut m = HashMap::new();
-
- for i in range_inclusive(1i, 1000) {
- m.insert(i, i);
- }
-
- let mut k = 1i;
-
- b.iter(|| {
- m.find(&(k + 400));
- m.find(&(k + 2000));
- m.pop(&k);
- m.insert(k + 1000, k + 1000);
- k += 1;
- })
-}
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <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.
-//
-// ignore-lexer-test FIXME #15883
-
-use clone::Clone;
-use cmp::{max, Eq, Equiv, PartialEq};
-use default::Default;
-use fmt::{mod, Show};
-use hash::{Hash, Hasher, RandomSipHasher};
-use iter::{mod, Iterator, FromIterator, Extendable};
-use kinds::Sized;
-use mem::{mod, replace};
-use num;
-use ops::{Deref, Index, IndexMut};
-use option::{Some, None, Option};
-use result::{Result, Ok, Err};
-
-use super::table;
-use super::table::{
- Bucket,
- Empty,
- EmptyBucket,
- Full,
- FullBucket,
- FullBucketImm,
- FullBucketMut,
- RawTable,
- SafeHash
-};
-
-const INITIAL_LOG2_CAP: uint = 5;
-pub const INITIAL_CAPACITY: uint = 1 << INITIAL_LOG2_CAP; // 2^5
-
-/// The default behavior of HashMap implements a load factor of 90.9%.
-/// This behavior is characterized by the following conditions:
-///
-/// - if size > 0.909 * capacity: grow
-/// - if size < 0.25 * capacity: shrink (if this won't bring capacity lower
-/// than the minimum)
-#[deriving(Clone)]
-struct DefaultResizePolicy {
- /// Doubled minimal capacity. The capacity must never drop below
- /// the minimum capacity. (The check happens before the capacity
- /// is potentially halved.)
- minimum_capacity2: uint
-}
-
-impl DefaultResizePolicy {
- fn new(new_capacity: uint) -> DefaultResizePolicy {
- DefaultResizePolicy {
- minimum_capacity2: new_capacity << 1
- }
- }
-
- #[inline]
- fn capacity_range(&self, new_size: uint) -> (uint, uint) {
- // Here, we are rephrasing the logic by specifying the ranges:
- //
- // - if `size * 1.1 < cap < size * 4`: don't resize
- // - if `cap < minimum_capacity * 2`: don't shrink
- // - otherwise, resize accordingly
- ((new_size * 11) / 10, max(new_size << 2, self.minimum_capacity2))
- }
-
- #[inline]
- fn reserve(&mut self, new_capacity: uint) {
- self.minimum_capacity2 = new_capacity << 1;
- }
-}
-
-// The main performance trick in this hashmap is called Robin Hood Hashing.
-// It gains its excellent performance from one essential operation:
-//
-// If an insertion collides with an existing element, and that element's
-// "probe distance" (how far away the element is from its ideal location)
-// is higher than how far we've already probed, swap the elements.
-//
-// This massively lowers variance in probe distance, and allows us to get very
-// high load factors with good performance. The 90% load factor I use is rather
-// conservative.
-//
-// > Why a load factor of approximately 90%?
-//
-// In general, all the distances to initial buckets will converge on the mean.
-// At a load factor of α, the odds of finding the target bucket after k
-// probes is approximately 1-α^k. If we set this equal to 50% (since we converge
-// on the mean) and set k=8 (64-byte cache line / 8-byte hash), α=0.92. I round
-// this down to make the math easier on the CPU and avoid its FPU.
-// Since on average we start the probing in the middle of a cache line, this
-// strategy pulls in two cache lines of hashes on every lookup. I think that's
-// pretty good, but if you want to trade off some space, it could go down to one
-// cache line on average with an α of 0.84.
-//
-// > Wait, what? Where did you get 1-α^k from?
-//
-// On the first probe, your odds of a collision with an existing element is α.
-// The odds of doing this twice in a row is approximately α^2. For three times,
-// α^3, etc. Therefore, the odds of colliding k times is α^k. The odds of NOT
-// colliding after k tries is 1-α^k.
-//
-// The paper from 1986 cited below mentions an implementation which keeps track
-// of the distance-to-initial-bucket histogram. This approach is not suitable
-// for modern architectures because it requires maintaining an internal data
-// structure. This allows very good first guesses, but we are most concerned
-// with guessing entire cache lines, not individual indexes. Furthermore, array
-// accesses are no longer linear and in one direction, as we have now. There
-// is also memory and cache pressure that this would entail that would be very
-// difficult to properly see in a microbenchmark.
-//
-// ## Future Improvements (FIXME!)
-//
-// Allow the load factor to be changed dynamically and/or at initialization.
-//
-// Also, would it be possible for us to reuse storage when growing the
-// underlying table? This is exactly the use case for 'realloc', and may
-// be worth exploring.
-//
-// ## Future Optimizations (FIXME!)
-//
-// Another possible design choice that I made without any real reason is
-// parameterizing the raw table over keys and values. Technically, all we need
-// is the size and alignment of keys and values, and the code should be just as
-// efficient (well, we might need one for power-of-two size and one for not...).
-// This has the potential to reduce code bloat in rust executables, without
-// really losing anything except 4 words (key size, key alignment, val size,
-// val alignment) which can be passed in to every call of a `RawTable` function.
-// This would definitely be an avenue worth exploring if people start complaining
-// about the size of rust executables.
-//
-// Annotate exceedingly likely branches in `table::make_hash`
-// and `search_hashed_generic` to reduce instruction cache pressure
-// and mispredictions once it becomes possible (blocked on issue #11092).
-//
-// Shrinking the table could simply reallocate in place after moving buckets
-// to the first half.
-//
-// The growth algorithm (fragment of the Proof of Correctness)
-// --------------------
-//
-// The growth algorithm is basically a fast path of the naive reinsertion-
-// during-resize algorithm. Other paths should never be taken.
-//
-// Consider growing a robin hood hashtable of capacity n. Normally, we do this
-// by allocating a new table of capacity `2n`, and then individually reinsert
-// each element in the old table into the new one. This guarantees that the
-// new table is a valid robin hood hashtable with all the desired statistical
-// properties. Remark that the order we reinsert the elements in should not
-// matter. For simplicity and efficiency, we will consider only linear
-// reinsertions, which consist of reinserting all elements in the old table
-// into the new one by increasing order of index. However we will not be
-// starting our reinsertions from index 0 in general. If we start from index
-// i, for the purpose of reinsertion we will consider all elements with real
-// index j < i to have virtual index n + j.
-//
-// Our hash generation scheme consists of generating a 64-bit hash and
-// truncating the most significant bits. When moving to the new table, we
-// simply introduce a new bit to the front of the hash. Therefore, if an
-// elements has ideal index i in the old table, it can have one of two ideal
-// locations in the new table. If the new bit is 0, then the new ideal index
-// is i. If the new bit is 1, then the new ideal index is n + i. Intutively,
-// we are producing two independent tables of size n, and for each element we
-// independently choose which table to insert it into with equal probability.
-// However the rather than wrapping around themselves on overflowing their
-// indexes, the first table overflows into the first, and the first into the
-// second. Visually, our new table will look something like:
-//
-// [yy_xxx_xxxx_xxx|xx_yyy_yyyy_yyy]
-//
-// Where x's are elements inserted into the first table, y's are elements
-// inserted into the second, and _'s are empty sections. We now define a few
-// key concepts that we will use later. Note that this is a very abstract
-// perspective of the table. A real resized table would be at least half
-// empty.
-//
-// Theorem: A linear robin hood reinsertion from the first ideal element
-// produces identical results to a linear naive reinsertion from the same
-// element.
-//
-// FIXME(Gankro, pczarn): review the proof and put it all in a separate doc.rs
-
-/// A hash map implementation which uses linear probing with Robin
-/// Hood bucket stealing.
-///
-/// The hashes are all keyed by the task-local random number generator
-/// on creation by default. This means that the ordering of the keys is
-/// randomized, but makes the tables more resistant to
-/// denial-of-service attacks (Hash DoS). This behaviour can be
-/// overridden with one of the constructors.
-///
-/// It is required that the keys implement the `Eq` and `Hash` traits, although
-/// this can frequently be achieved by using `#[deriving(Eq, Hash)]`.
-///
-/// Relevant papers/articles:
-///
-/// 1. Pedro Celis. ["Robin Hood Hashing"](https://cs.uwaterloo.ca/research/tr/1986/CS-86-14.pdf)
-/// 2. Emmanuel Goossaert. ["Robin Hood
-/// hashing"](http://codecapsule.com/2013/11/11/robin-hood-hashing/)
-/// 3. Emmanuel Goossaert. ["Robin Hood hashing: backward shift
-/// deletion"](http://codecapsule.com/2013/11/17/robin-hood-hashing-backward-shift-deletion/)
-///
-/// # Example
-///
-/// ```
-/// use std::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 Huckleberry Finn", "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);
-/// }
-/// ```
-///
-/// The easiest way to use `HashMap` with a custom type is to derive `Eq` and `Hash`.
-/// We must also derive `PartialEq`.
-///
-/// ```
-/// use std::collections::HashMap;
-///
-/// #[deriving(Hash, Eq, PartialEq, Show)]
-/// struct Viking<'a> {
-/// name: &'a str,
-/// power: uint,
-/// }
-///
-/// let mut vikings = HashMap::new();
-///
-/// vikings.insert("Norway", Viking { name: "Einar", power: 9u });
-/// vikings.insert("Denmark", Viking { name: "Olaf", power: 4u });
-/// vikings.insert("Iceland", Viking { name: "Harald", power: 8u });
-///
-/// // Use derived implementation to print the vikings.
-/// for (land, viking) in vikings.iter() {
-/// println!("{} at {}", viking, land);
-/// }
-/// ```
-#[deriving(Clone)]
-pub struct HashMap<K, V, H = RandomSipHasher> {
- // All hashes are keyed on these values, to prevent hash collision attacks.
- hasher: H,
-
- table: RawTable<K, V>,
-
- // We keep this at the end since it might as well have tail padding.
- resize_policy: DefaultResizePolicy,
-}
-
-/// Search for a pre-hashed key.
-fn search_hashed_generic<K, V, M: Deref<RawTable<K, V>>>(table: M,
- hash: &SafeHash,
- is_match: |&K| -> bool)
- -> SearchResult<K, V, M> {
- let size = table.size();
- let mut probe = Bucket::new(table, hash);
- let ib = probe.index();
-
- while probe.index() != ib + size {
- let full = match probe.peek() {
- Empty(b) => return TableRef(b.into_table()), // hit an empty bucket
- Full(b) => b
- };
-
- if full.distance() + ib < full.index() {
- // We can finish the search early if we hit any bucket
- // with a lower distance to initial bucket than we've probed.
- return TableRef(full.into_table());
- }
-
- // If the hash doesn't match, it can't be this one..
- if *hash == full.hash() {
- let matched = {
- let (k, _) = full.read();
- is_match(k)
- };
-
- // If the key doesn't match, it can't be this one..
- if matched {
- return FoundExisting(full);
- }
- }
-
- probe = full.next();
- }
-
- TableRef(probe.into_table())
-}
-
-fn search_hashed<K: Eq, V, M: Deref<RawTable<K, V>>>(table: M, hash: &SafeHash, k: &K)
- -> SearchResult<K, V, M> {
- search_hashed_generic(table, hash, |k_| *k == *k_)
-}
-
-fn pop_internal<K, V>(starting_bucket: FullBucketMut<K, V>) -> (K, V) {
- let (empty, retkey, retval) = starting_bucket.take();
- let mut gap = match empty.gap_peek() {
- Some(b) => b,
- None => return (retkey, retval)
- };
-
- while gap.full().distance() != 0 {
- gap = match gap.shift() {
- Some(b) => b,
- None => break
- };
- }
-
- // Now we've done all our shifting. Return the value we grabbed earlier.
- return (retkey, retval);
-}
-
-/// Perform robin hood bucket stealing at the given `bucket`. You must
-/// also pass the position of that bucket's initial bucket so we don't have
-/// to recalculate it.
-///
-/// `hash`, `k`, and `v` are the elements to "robin hood" into the hashtable.
-fn robin_hood<'a, K: 'a, V: 'a>(mut bucket: FullBucketMut<'a, K, V>,
- mut ib: uint,
- mut hash: SafeHash,
- mut k: K,
- mut v: V)
- -> &'a mut V {
- let starting_index = bucket.index();
- let size = {
- let table = bucket.table(); // FIXME "lifetime too short".
- table.size()
- };
- // There can be at most `size - dib` buckets to displace, because
- // in the worst case, there are `size` elements and we already are
- // `distance` buckets away from the initial one.
- let idx_end = starting_index + size - bucket.distance();
-
- loop {
- let (old_hash, old_key, old_val) = bucket.replace(hash, k, v);
- loop {
- let probe = bucket.next();
- assert!(probe.index() != idx_end);
-
- let full_bucket = match probe.peek() {
- table::Empty(bucket) => {
- // Found a hole!
- let b = bucket.put(old_hash, old_key, old_val);
- // Now that it's stolen, just read the value's pointer
- // right out of the table!
- let (_, v) = Bucket::at_index(b.into_table(), starting_index).peek()
- .expect_full()
- .into_mut_refs();
- return v;
- },
- table::Full(bucket) => bucket
- };
-
- let probe_ib = full_bucket.index() - full_bucket.distance();
-
- bucket = full_bucket;
-
- // Robin hood! Steal the spot.
- if ib < probe_ib {
- ib = probe_ib;
- hash = old_hash;
- k = old_key;
- v = old_val;
- break;
- }
- }
- }
-}
-
-/// A result that works like Option<FullBucket<..>> but preserves
-/// the reference that grants us access to the table in any case.
-enum SearchResult<K, V, M> {
- // This is an entry that holds the given key:
- FoundExisting(FullBucket<K, V, M>),
-
- // There was no such entry. The reference is given back:
- TableRef(M)
-}
-
-impl<K, V, M> SearchResult<K, V, M> {
- fn into_option(self) -> Option<FullBucket<K, V, M>> {
- match self {
- FoundExisting(bucket) => Some(bucket),
- TableRef(_) => None
- }
- }
-}
-
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
- fn make_hash<Sized? X: Hash<S>>(&self, x: &X) -> SafeHash {
- table::make_hash(&self.hasher, x)
- }
-
- fn search_equiv<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a self, q: &Q)
- -> Option<FullBucketImm<'a, K, V>> {
- let hash = self.make_hash(q);
- search_hashed_generic(&self.table, &hash, |k| q.equiv(k)).into_option()
- }
-
- fn search_equiv_mut<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a mut self, q: &Q)
- -> Option<FullBucketMut<'a, K, V>> {
- let hash = self.make_hash(q);
- search_hashed_generic(&mut self.table, &hash, |k| q.equiv(k)).into_option()
- }
-
- /// Search for a key, yielding the index if it's found in the hashtable.
- /// If you already have the hash for the key lying around, use
- /// search_hashed.
- fn search<'a>(&'a self, k: &K) -> Option<FullBucketImm<'a, K, V>> {
- let hash = self.make_hash(k);
- search_hashed(&self.table, &hash, k).into_option()
- }
-
- fn search_mut<'a>(&'a mut self, k: &K) -> Option<FullBucketMut<'a, K, V>> {
- let hash = self.make_hash(k);
- search_hashed(&mut self.table, &hash, k).into_option()
- }
-
- // The caller should ensure that invariants by Robin Hood Hashing hold.
- fn insert_hashed_ordered(&mut self, hash: SafeHash, k: K, v: V) {
- let cap = self.table.capacity();
- let mut buckets = Bucket::new(&mut self.table, &hash);
- let ib = buckets.index();
-
- while buckets.index() != ib + cap {
- // We don't need to compare hashes for value swap.
- // Not even DIBs for Robin Hood.
- buckets = match buckets.peek() {
- Empty(empty) => {
- empty.put(hash, k, v);
- return;
- }
- Full(b) => b.into_bucket()
- };
- buckets.next();
- }
- panic!("Internal HashMap error: Out of space.");
- }
-}
-
-impl<K: Hash + Eq, V> HashMap<K, V, RandomSipHasher> {
- /// Create an empty HashMap.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- /// let mut map: HashMap<&str, int> = HashMap::with_capacity(10);
- /// ```
- #[inline]
- pub fn new() -> HashMap<K, V, RandomSipHasher> {
- let hasher = RandomSipHasher::new();
- HashMap::with_hasher(hasher)
- }
-
- /// Creates an empty hash map with the given initial capacity.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- /// let mut map: HashMap<&str, int> = HashMap::with_capacity(10);
- /// ```
- #[inline]
- pub fn with_capacity(capacity: uint) -> HashMap<K, V, RandomSipHasher> {
- let hasher = RandomSipHasher::new();
- HashMap::with_capacity_and_hasher(capacity, hasher)
- }
-}
-
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
- /// Creates an empty hashmap which will use the given hasher to hash keys.
- ///
- /// The creates map has the default initial capacity.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- /// use std::hash::sip::SipHasher;
- ///
- /// let h = SipHasher::new();
- /// let mut map = HashMap::with_hasher(h);
- /// map.insert(1i, 2u);
- /// ```
- #[inline]
- pub fn with_hasher(hasher: H) -> HashMap<K, V, H> {
- HashMap {
- hasher: hasher,
- resize_policy: DefaultResizePolicy::new(INITIAL_CAPACITY),
- table: RawTable::new(0),
- }
- }
-
- /// Create an empty HashMap with space for at least `capacity`
- /// elements, using `hasher` to hash the keys.
- ///
- /// Warning: `hasher` is normally randomly generated, and
- /// is designed to allow HashMaps to be resistant to attacks that
- /// cause many collisions and very poor performance. Setting it
- /// manually using this function can expose a DoS attack vector.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- /// use std::hash::sip::SipHasher;
- ///
- /// let h = SipHasher::new();
- /// let mut map = HashMap::with_capacity_and_hasher(10, h);
- /// map.insert(1i, 2u);
- /// ```
- #[inline]
- pub fn with_capacity_and_hasher(capacity: uint, hasher: H) -> HashMap<K, V, H> {
- let cap = num::next_power_of_two(max(INITIAL_CAPACITY, capacity));
- HashMap {
- hasher: hasher,
- resize_policy: DefaultResizePolicy::new(cap),
- table: RawTable::new(cap),
- }
- }
-
- /// The hashtable will never try to shrink below this size. You can use
- /// this function to reduce reallocations if your hashtable frequently
- /// grows and shrinks by large amounts.
- ///
- /// This function has no effect on the operational semantics of the
- /// hashtable, only on performance.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- /// let mut map: HashMap<&str, int> = HashMap::new();
- /// map.reserve(10);
- /// ```
- pub fn reserve(&mut self, new_minimum_capacity: uint) {
- let cap = num::next_power_of_two(
- max(INITIAL_CAPACITY, new_minimum_capacity));
-
- self.resize_policy.reserve(cap);
-
- if self.table.capacity() < cap {
- self.resize(cap);
- }
- }
-
- /// Resizes the internal vectors to a new capacity. It's your responsibility to:
- /// 1) Make sure the new capacity is enough for all the elements, accounting
- /// for the load factor.
- /// 2) Ensure new_capacity is a power of two.
- fn resize(&mut self, new_capacity: uint) {
- assert!(self.table.size() <= new_capacity);
- assert!(num::is_power_of_two(new_capacity));
-
- let mut old_table = replace(&mut self.table, RawTable::new(new_capacity));
- let old_size = old_table.size();
-
- if old_table.capacity() == 0 || old_table.size() == 0 {
- return;
- }
-
- if new_capacity < old_table.capacity() {
- // Shrink the table. Naive algorithm for resizing:
- for (h, k, v) in old_table.into_iter() {
- self.insert_hashed_nocheck(h, k, v);
- }
- } else {
- // Grow the table.
- // Specialization of the other branch.
- let mut bucket = Bucket::first(&mut old_table);
-
- // "So a few of the first shall be last: for many be called,
- // but few chosen."
- //
- // We'll most likely encounter a few buckets at the beginning that
- // have their initial buckets near the end of the table. They were
- // placed at the beginning as the probe wrapped around the table
- // during insertion. We must skip forward to a bucket that won't
- // get reinserted too early and won't unfairly steal others spot.
- // This eliminates the need for robin hood.
- loop {
- bucket = match bucket.peek() {
- Full(full) => {
- if full.distance() == 0 {
- // This bucket occupies its ideal spot.
- // It indicates the start of another "cluster".
- bucket = full.into_bucket();
- break;
- }
- // Leaving this bucket in the last cluster for later.
- full.into_bucket()
- }
- Empty(b) => {
- // Encountered a hole between clusters.
- b.into_bucket()
- }
- };
- bucket.next();
- }
-
- // This is how the buckets might be laid out in memory:
- // ($ marks an initialized bucket)
- // ________________
- // |$$$_$$$$$$_$$$$$|
- //
- // But we've skipped the entire initial cluster of buckets
- // and will continue iteration in this order:
- // ________________
- // |$$$$$$_$$$$$
- // ^ wrap around once end is reached
- // ________________
- // $$$_____________|
- // ^ exit once table.size == 0
- loop {
- bucket = match bucket.peek() {
- Full(bucket) => {
- let h = bucket.hash();
- let (b, k, v) = bucket.take();
- self.insert_hashed_ordered(h, k, v);
- {
- let t = b.table(); // FIXME "lifetime too short".
- if t.size() == 0 { break }
- };
- b.into_bucket()
- }
- Empty(b) => b.into_bucket()
- };
- bucket.next();
- }
- }
-
- assert_eq!(self.table.size(), old_size);
- }
-
- /// Performs any necessary resize operations, such that there's space for
- /// new_size elements.
- fn make_some_room(&mut self, new_size: uint) {
- let (grow_at, shrink_at) = self.resize_policy.capacity_range(new_size);
- let cap = self.table.capacity();
-
- // An invalid value shouldn't make us run out of space.
- debug_assert!(grow_at >= new_size);
-
- if cap <= grow_at {
- let new_capacity = max(cap << 1, INITIAL_CAPACITY);
- self.resize(new_capacity);
- } else if shrink_at <= cap {
- let new_capacity = cap >> 1;
- self.resize(new_capacity);
- }
- }
-
- /// Insert a pre-hashed key-value pair, without first checking
- /// that there's enough room in the buckets. Returns a reference to the
- /// newly insert value.
- ///
- /// If the key already exists, the hashtable will be returned untouched
- /// and a reference to the existing element will be returned.
- fn insert_hashed_nocheck(&mut self, hash: SafeHash, k: K, v: V) -> &mut V {
- self.insert_or_replace_with(hash, k, v, |_, _, _| ())
- }
-
- fn insert_or_replace_with<'a>(&'a mut self,
- hash: SafeHash,
- k: K,
- v: V,
- found_existing: |&mut K, &mut V, V|)
- -> &'a mut V {
- // Worst case, we'll find one empty bucket among `size + 1` buckets.
- let size = self.table.size();
- let mut probe = Bucket::new(&mut self.table, &hash);
- let ib = probe.index();
-
- loop {
- let mut bucket = match probe.peek() {
- Empty(bucket) => {
- // Found a hole!
- let bucket = bucket.put(hash, k, v);
- let (_, val) = bucket.into_mut_refs();
- return val;
- },
- Full(bucket) => bucket
- };
-
- if bucket.hash() == hash {
- let found_match = {
- let (bucket_k, _) = bucket.read_mut();
- k == *bucket_k
- };
- if found_match {
- let (bucket_k, bucket_v) = bucket.into_mut_refs();
- debug_assert!(k == *bucket_k);
- // Key already exists. Get its reference.
- found_existing(bucket_k, bucket_v, v);
- return bucket_v;
- }
- }
-
- let robin_ib = bucket.index() as int - bucket.distance() as int;
-
- if (ib as int) < robin_ib {
- // Found a luckier bucket than me. Better steal his spot.
- return robin_hood(bucket, robin_ib as uint, hash, k, v);
- }
-
- probe = bucket.next();
- assert!(probe.index() != ib + size + 1);
- }
- }
-
- /// Retrieves a mutable value for the given key.
- /// See [`find_mut`](../trait.MutableMap.html#tymethod.find_mut) for a non-panicking
- /// alternative.
- ///
- /// # Failure
- ///
- /// Fails if the key is not present.
- ///
- /// # Example
- ///
- /// ```
- /// # #![allow(deprecated)]
- /// use std::collections::HashMap;
- ///
- /// let mut map = HashMap::new();
- /// map.insert("a", 1i);
- /// {
- /// // val will freeze map to prevent usage during its lifetime
- /// let val = map.get_mut(&"a");
- /// *val = 40;
- /// }
- /// assert_eq!(map["a"], 40);
- ///
- /// // A more direct way could be:
- /// *map.get_mut(&"a") = -2;
- /// assert_eq!(map["a"], -2);
- /// ```
- #[deprecated = "use indexing instead: `&mut map[key]`"]
- pub fn get_mut<'a>(&'a mut self, k: &K) -> &'a mut V {
- &mut self[*k]
- }
-
- /// Return true if the map contains a value for the specified key,
- /// using equivalence.
- ///
- /// See [pop_equiv](#method.pop_equiv) for an extended example.
- pub fn contains_key_equiv<Sized? Q: Hash<S> + Equiv<K>>(&self, key: &Q) -> bool {
- self.search_equiv(key).is_some()
- }
-
- /// Return the value corresponding to the key in the map, using
- /// equivalence.
- ///
- /// See [pop_equiv](#method.pop_equiv) for an extended example.
- pub fn find_equiv<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a self, k: &Q) -> Option<&'a V> {
- match self.search_equiv(k) {
- None => None,
- Some(bucket) => {
- let (_, v_ref) = bucket.into_refs();
- Some(v_ref)
- }
- }
- }
-
- /// Remove an equivalent key from the map, returning the value at the
- /// key if the key was previously in the map.
- ///
- /// # Example
- ///
- /// This is a slightly silly example where we define the number's
- /// parity as the equivalence class. It is important that the
- /// values hash the same, which is why we implement `Hash`.
- ///
- /// ```
- /// use std::collections::HashMap;
- /// use std::hash::Hash;
- /// use std::hash::sip::SipState;
- ///
- /// #[deriving(Eq, PartialEq)]
- /// struct EvenOrOdd {
- /// num: uint
- /// };
- ///
- /// impl Hash for EvenOrOdd {
- /// fn hash(&self, state: &mut SipState) {
- /// let parity = self.num % 2;
- /// parity.hash(state);
- /// }
- /// }
- ///
- /// impl Equiv<EvenOrOdd> for EvenOrOdd {
- /// fn equiv(&self, other: &EvenOrOdd) -> bool {
- /// self.num % 2 == other.num % 2
- /// }
- /// }
- ///
- /// let mut map = HashMap::new();
- /// map.insert(EvenOrOdd { num: 3 }, "foo");
- ///
- /// assert!(map.contains_key_equiv(&EvenOrOdd { num: 1 }));
- /// assert!(!map.contains_key_equiv(&EvenOrOdd { num: 4 }));
- ///
- /// assert_eq!(map.find_equiv(&EvenOrOdd { num: 5 }), Some(&"foo"));
- /// assert_eq!(map.find_equiv(&EvenOrOdd { num: 2 }), None);
- ///
- /// assert_eq!(map.pop_equiv(&EvenOrOdd { num: 1 }), Some("foo"));
- /// assert_eq!(map.pop_equiv(&EvenOrOdd { num: 2 }), None);
- ///
- /// ```
- #[experimental]
- pub fn pop_equiv<Sized? Q:Hash<S> + Equiv<K>>(&mut self, k: &Q) -> Option<V> {
- if self.table.size() == 0 {
- return None
- }
-
- let potential_new_size = self.table.size() - 1;
- self.make_some_room(potential_new_size);
-
- match self.search_equiv_mut(k) {
- Some(bucket) => {
- let (_k, val) = pop_internal(bucket);
- Some(val)
- }
- _ => None
- }
- }
-
- /// An iterator visiting all keys in arbitrary order.
- /// Iterator element type is `&'a K`.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut map = HashMap::new();
- /// map.insert("a", 1i);
- /// map.insert("b", 2);
- /// map.insert("c", 3);
- ///
- /// for key in map.keys() {
- /// println!("{}", key);
- /// }
- /// ```
- pub fn keys(&self) -> Keys<K, V> {
- self.iter().map(|(k, _v)| k)
- }
-
- /// An iterator visiting all values in arbitrary order.
- /// Iterator element type is `&'a V`.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut map = HashMap::new();
- /// map.insert("a", 1i);
- /// map.insert("b", 2);
- /// map.insert("c", 3);
- ///
- /// for key in map.values() {
- /// println!("{}", key);
- /// }
- /// ```
- pub fn values(&self) -> Values<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)`.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut map = HashMap::new();
- /// map.insert("a", 1i);
- /// map.insert("b", 2);
- /// map.insert("c", 3);
- ///
- /// for (key, val) in map.iter() {
- /// println!("key: {} val: {}", key, val);
- /// }
- /// ```
- pub fn iter(&self) -> Entries<K, V> {
- Entries { inner: self.table.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)`.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut map = HashMap::new();
- /// map.insert("a", 1i);
- /// map.insert("b", 2);
- /// map.insert("c", 3);
- ///
- /// // Update all values
- /// for (_, val) in map.iter_mut() {
- /// *val *= 2;
- /// }
- ///
- /// for (key, val) in map.iter() {
- /// println!("key: {} val: {}", key, val);
- /// }
- /// ```
- pub fn iter_mut(&mut self) -> MutEntries<K, V> {
- MutEntries { inner: self.table.iter_mut() }
- }
-
- /// 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.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut map = HashMap::new();
- /// map.insert("a", 1i);
- /// map.insert("b", 2);
- /// map.insert("c", 3);
- ///
- /// // Not possible with .iter()
- /// let vec: Vec<(&str, int)> = map.into_iter().collect();
- /// ```
- pub fn into_iter(self) -> MoveEntries<K, V> {
- MoveEntries {
- inner: self.table.into_iter().map(|(_, k, v)| (k, v))
- }
- }
-
- /// Gets the given key's corresponding entry in the map for in-place manipulation
- pub fn entry<'a>(&'a mut self, key: K) -> Entry<'a, K, V> {
- // Gotta resize now, and we don't know which direction, so try both?
- let size = self.table.size();
- self.make_some_room(size + 1);
- if size > 0 {
- self.make_some_room(size - 1);
- }
-
- let hash = self.make_hash(&key);
- search_entry_hashed(&mut self.table, hash, key)
- }
-
- /// Return the number of elements in the map.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut a = HashMap::new();
- /// assert_eq!(a.len(), 0);
- /// a.insert(1u, "a");
- /// assert_eq!(a.len(), 1);
- /// ```
- pub fn len(&self) -> uint { self.table.size() }
-
- /// Return true if the map contains no elements.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut a = HashMap::new();
- /// assert!(a.is_empty());
- /// a.insert(1u, "a");
- /// assert!(!a.is_empty());
- /// ```
- #[inline]
- pub fn is_empty(&self) -> bool { self.len() == 0 }
-
- /// Clears the map, removing all key-value pairs. Keeps the allocated memory
- /// for reuse.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut a = HashMap::new();
- /// a.insert(1u, "a");
- /// a.clear();
- /// assert!(a.is_empty());
- /// ```
- pub fn clear(&mut self) {
- // Prevent reallocations from happening from now on. Makes it possible
- // for the map to be reused but has a downside: reserves permanently.
- self.resize_policy.reserve(self.table.size());
-
- let cap = self.table.capacity();
- let mut buckets = Bucket::first(&mut self.table);
-
- while buckets.index() != cap {
- buckets = match buckets.peek() {
- Empty(b) => b.next(),
- Full(full) => {
- let (b, _, _) = full.take();
- b.next()
- }
- };
- }
- }
-
- /// Returns a reference to the value corresponding to the key.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut map = HashMap::new();
- /// map.insert(1u, "a");
- /// assert_eq!(map.find(&1), Some(&"a"));
- /// assert_eq!(map.find(&2), None);
- /// ```
- pub fn find<'a>(&'a self, k: &K) -> Option<&'a V> {
- self.search(k).map(|bucket| {
- let (_, v) = bucket.into_refs();
- v
- })
- }
-
- /// Returns true if the map contains a value for the specified key.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut map = HashMap::new();
- /// map.insert(1u, "a");
- /// assert_eq!(map.contains_key(&1), true);
- /// assert_eq!(map.contains_key(&2), false);
- /// ```
- pub fn contains_key(&self, k: &K) -> bool {
- self.search(k).is_some()
- }
-
- /// Returns a mutable reference to the value corresponding to the key.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut map = HashMap::new();
- /// map.insert(1u, "a");
- /// match map.find_mut(&1) {
- /// Some(x) => *x = "b",
- /// None => (),
- /// }
- /// assert_eq!(map[1], "b");
- /// ```
- pub fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> {
- match self.search_mut(k) {
- Some(bucket) => {
- let (_, v) = bucket.into_mut_refs();
- Some(v)
- }
- _ => None
- }
- }
-
- /// Inserts a key-value pair into the map. An existing value for a
- /// key is replaced by the new value. Returns `true` if the key did
- /// not already exist in the map.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut map = HashMap::new();
- /// assert_eq!(map.insert(2u, "value"), true);
- /// assert_eq!(map.insert(2, "value2"), false);
- /// assert_eq!(map[2], "value2");
- /// ```
- #[inline]
- pub fn insert(&mut self, key: K, value: V) -> bool {
- self.swap(key, value).is_none()
- }
-
- /// Removes a key-value pair from the map. Returns `true` if the key
- /// was present in the map.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut map = HashMap::new();
- /// assert_eq!(map.remove(&1u), false);
- /// map.insert(1, "a");
- /// assert_eq!(map.remove(&1), true);
- /// ```
- #[inline]
- pub fn remove(&mut self, key: &K) -> bool {
- self.pop(key).is_some()
- }
-
- /// Inserts a key-value pair from the map. If the key already had a value
- /// present in the map, that value is returned. Otherwise, `None` is returned.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut map = HashMap::new();
- /// assert_eq!(map.swap(37u, "a"), None);
- /// assert_eq!(map.is_empty(), false);
- ///
- /// map.insert(37, "b");
- /// assert_eq!(map.swap(37, "c"), Some("b"));
- /// assert_eq!(map[37], "c");
- /// ```
- pub fn swap(&mut self, k: K, v: V) -> Option<V> {
- let hash = self.make_hash(&k);
- let potential_new_size = self.table.size() + 1;
- self.make_some_room(potential_new_size);
-
- let mut retval = None;
- self.insert_or_replace_with(hash, k, v, |_, val_ref, val| {
- retval = Some(replace(val_ref, val));
- });
- retval
- }
-
- /// Removes a key from the map, returning the value at the key if the key
- /// was previously in the map.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut map = HashMap::new();
- /// map.insert(1u, "a");
- /// assert_eq!(map.pop(&1), Some("a"));
- /// assert_eq!(map.pop(&1), None);
- /// ```
- pub fn pop(&mut self, k: &K) -> Option<V> {
- if self.table.size() == 0 {
- return None
- }
-
- let potential_new_size = self.table.size() - 1;
- self.make_some_room(potential_new_size);
-
- self.search_mut(k).map(|bucket| {
- let (_k, val) = pop_internal(bucket);
- val
- })
- }
-}
-
-fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable<K,V>, hash: SafeHash, k: K)
- -> Entry<'a, K, V> {
- // Worst case, we'll find one empty bucket among `size + 1` buckets.
- let size = table.size();
- let mut probe = Bucket::new(table, &hash);
- let ib = probe.index();
-
- loop {
- let bucket = match probe.peek() {
- Empty(bucket) => {
- // Found a hole!
- return Vacant(VacantEntry {
- hash: hash,
- key: k,
- elem: NoElem(bucket),
- });
- },
- Full(bucket) => bucket
- };
-
- if bucket.hash() == hash {
- let is_eq = {
- let (bucket_k, _) = bucket.read();
- k == *bucket_k
- };
-
- if is_eq {
- return Occupied(OccupiedEntry{
- elem: bucket,
- });
- }
- }
-
- let robin_ib = bucket.index() as int - bucket.distance() as int;
-
- if (ib as int) < robin_ib {
- // Found a luckier bucket than me. Better steal his spot.
- return Vacant(VacantEntry {
- hash: hash,
- key: k,
- elem: NeqElem(bucket, robin_ib as uint),
- });
- }
-
- probe = bucket.next();
- assert!(probe.index() != ib + size + 1);
- }
-}
-
-impl<K: Eq + Hash<S>, V: Clone, S, H: Hasher<S>> HashMap<K, V, H> {
- /// Return a copy of the value corresponding to the key.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut map: HashMap<uint, String> = HashMap::new();
- /// map.insert(1u, "foo".to_string());
- /// let s: String = map.find_copy(&1).unwrap();
- /// ```
- pub fn find_copy(&self, k: &K) -> Option<V> {
- self.find(k).map(|v| (*v).clone())
- }
-
- /// Return a copy of the value corresponding to the key.
- ///
- /// # Failure
- ///
- /// Fails if the key is not present.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashMap;
- ///
- /// let mut map: HashMap<uint, String> = HashMap::new();
- /// map.insert(1u, "foo".to_string());
- /// let s: String = map.get_copy(&1);
- /// ```
- pub fn get_copy(&self, k: &K) -> V {
- self[*k].clone()
- }
-}
-
-impl<K: Eq + Hash<S>, V: PartialEq, S, H: Hasher<S>> PartialEq for HashMap<K, V, H> {
- fn eq(&self, other: &HashMap<K, V, H>) -> bool {
- if self.len() != other.len() { return false; }
-
- self.iter().all(|(key, value)|
- other.find(key).map_or(false, |v| *value == *v)
- )
- }
-}
-
-impl<K: Eq + Hash<S>, V: Eq, S, H: Hasher<S>> Eq for HashMap<K, V, H> {}
-
-impl<K: Eq + Hash<S> + Show, V: Show, S, H: Hasher<S>> Show for HashMap<K, V, H> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- try!(write!(f, "{{"));
-
- for (i, (k, v)) in self.iter().enumerate() {
- if i != 0 { try!(write!(f, ", ")); }
- try!(write!(f, "{}: {}", *k, *v));
- }
-
- write!(f, "}}")
- }
-}
-
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Default for HashMap<K, V, H> {
- fn default() -> HashMap<K, V, H> {
- HashMap::with_hasher(Default::default())
- }
-}
-
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Index<K, V> for HashMap<K, V, H> {
- #[inline]
- fn index<'a>(&'a self, index: &K) -> &'a V {
- self.find(index).expect("no entry found for key")
- }
-}
-
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> IndexMut<K, V> for HashMap<K, V, H> {
- #[inline]
- fn index_mut<'a>(&'a mut self, index: &K) -> &'a mut V {
- match self.find_mut(index) {
- Some(v) => v,
- None => panic!("no entry found for key")
- }
- }
-}
-
-/// HashMap iterator
-pub struct Entries<'a, K: 'a, V: 'a> {
- inner: table::Entries<'a, K, V>
-}
-
-/// HashMap mutable values iterator
-pub struct MutEntries<'a, K: 'a, V: 'a> {
- inner: table::MutEntries<'a, K, V>
-}
-
-/// HashMap move iterator
-pub struct MoveEntries<K, V> {
- inner: iter::Map<'static, (SafeHash, K, V), (K, V), table::MoveEntries<K, V>>
-}
-
-/// A view into a single occupied location in a HashMap
-pub struct OccupiedEntry<'a, K:'a, V:'a> {
- elem: FullBucket<K, V, &'a mut RawTable<K, V>>,
-}
-
-/// A view into a single empty location in a HashMap
-pub struct VacantEntry<'a, K:'a, V:'a> {
- hash: SafeHash,
- key: K,
- elem: VacantEntryState<K,V, &'a mut RawTable<K, V>>,
-}
-
-/// A view into a single location in a map, which may be vacant or occupied
-pub enum Entry<'a, K:'a, V:'a> {
- /// An occupied Entry
- Occupied(OccupiedEntry<'a, K, V>),
- /// A vacant Entry
- Vacant(VacantEntry<'a, K, V>),
-}
-
-/// Possible states of a VacantEntry
-enum VacantEntryState<K, V, M> {
- /// The index is occupied, but the key to insert has precedence,
- /// and will kick the current one out on insertion
- NeqElem(FullBucket<K, V, M>, uint),
- /// The index is genuinely vacant
- NoElem(EmptyBucket<K, V, M>),
-}
-
-impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
- #[inline]
- fn next(&mut self) -> Option<(&'a K, &'a V)> {
- self.inner.next()
- }
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- self.inner.size_hint()
- }
-}
-
-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)> {
- self.inner.next()
- }
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- self.inner.size_hint()
- }
-}
-
-impl<K, V> Iterator<(K, V)> for MoveEntries<K, V> {
- #[inline]
- fn next(&mut self) -> Option<(K, V)> {
- self.inner.next()
- }
- #[inline]
- fn size_hint(&self) -> (uint, Option<uint>) {
- self.inner.size_hint()
- }
-}
-
-impl<'a, K, V> OccupiedEntry<'a, K, V> {
- /// Gets a reference to the value in the entry
- pub fn get(&self) -> &V {
- let (_, v) = self.elem.read();
- v
- }
-
- /// Gets a mutable reference to the value in the entry
- pub fn get_mut(&mut self) -> &mut V {
- let (_, v) = self.elem.read_mut();
- v
- }
-
- /// Converts the OccupiedEntry into a mutable reference to the value in the entry
- /// with a lifetime bound to the map itself
- pub fn into_mut(self) -> &'a mut V {
- let (_, v) = self.elem.into_mut_refs();
- v
- }
-
- /// Sets the value of the entry, and returns the entry's old value
- pub fn set(&mut self, mut value: V) -> V {
- let old_value = self.get_mut();
- mem::swap(&mut value, old_value);
- value
- }
-
- /// Takes the value out of the entry, and returns it
- pub fn take(self) -> V {
- let (_, _, v) = self.elem.take();
- v
- }
-}
-
-impl<'a, K, V> VacantEntry<'a, K, V> {
- /// Sets the value of the entry with the VacantEntry's key,
- /// and returns a mutable reference to it
- pub fn set(self, value: V) -> &'a mut V {
- match self.elem {
- NeqElem(bucket, ib) => {
- robin_hood(bucket, ib, self.hash, self.key, value)
- }
- NoElem(bucket) => {
- let full = bucket.put(self.hash, self.key, value);
- let (_, v) = full.into_mut_refs();
- 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>>;
-
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> FromIterator<(K, V)> for HashMap<K, V, H> {
- fn from_iter<T: Iterator<(K, V)>>(iter: T) -> HashMap<K, V, H> {
- let (lower, _) = iter.size_hint();
- let mut map = HashMap::with_capacity_and_hasher(lower, Default::default());
- map.extend(iter);
- map
- }
-}
-
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Extendable<(K, V)> for HashMap<K, V, H> {
- fn extend<T: Iterator<(K, V)>>(&mut self, mut iter: T) {
- for (k, v) in iter {
- self.insert(k, v);
- }
- }
-}
-
-#[cfg(test)]
-mod test_map {
- use prelude::*;
-
- use super::HashMap;
- use super::{Occupied, Vacant};
- use cmp::Equiv;
- use hash;
- use iter::{Iterator,range_inclusive,range_step_inclusive};
- use cell::RefCell;
-
- struct KindaIntLike(int);
-
- impl Equiv<int> for KindaIntLike {
- fn equiv(&self, other: &int) -> bool {
- let KindaIntLike(this) = *self;
- this == *other
- }
- }
- impl<S: hash::Writer> hash::Hash<S> for KindaIntLike {
- fn hash(&self, state: &mut S) {
- let KindaIntLike(this) = *self;
- this.hash(state)
- }
- }
-
- #[test]
- fn test_create_capacity_zero() {
- let mut m = HashMap::with_capacity(0);
-
- assert!(m.insert(1i, 1i));
-
- assert!(m.contains_key(&1));
- assert!(!m.contains_key(&0));
- }
-
- #[test]
- fn test_insert() {
- let mut m = HashMap::new();
- assert_eq!(m.len(), 0);
- assert!(m.insert(1i, 2i));
- assert_eq!(m.len(), 1);
- assert!(m.insert(2i, 4i));
- assert_eq!(m.len(), 2);
- assert_eq!(*m.find(&1).unwrap(), 2);
- assert_eq!(*m.find(&2).unwrap(), 4);
- }
-
- local_data_key!(drop_vector: RefCell<Vec<int>>)
-
- #[deriving(Hash, PartialEq, Eq)]
- struct Dropable {
- k: uint
- }
-
- impl Dropable {
- fn new(k: uint) -> Dropable {
- let v = drop_vector.get().unwrap();
- v.borrow_mut().as_mut_slice()[k] += 1;
-
- Dropable { k: k }
- }
- }
-
- impl Drop for Dropable {
- fn drop(&mut self) {
- let v = drop_vector.get().unwrap();
- v.borrow_mut().as_mut_slice()[self.k] -= 1;
- }
- }
-
- impl Clone for Dropable {
- fn clone(&self) -> Dropable {
- Dropable::new(self.k)
- }
- }
-
- #[test]
- fn test_drops() {
- drop_vector.replace(Some(RefCell::new(Vec::from_elem(200, 0i))));
-
- {
- let mut m = HashMap::new();
-
- let v = drop_vector.get().unwrap();
- for i in range(0u, 200) {
- assert_eq!(v.borrow().as_slice()[i], 0);
- }
- drop(v);
-
- for i in range(0u, 100) {
- let d1 = Dropable::new(i);
- let d2 = Dropable::new(i+100);
- m.insert(d1, d2);
- }
-
- let v = drop_vector.get().unwrap();
- for i in range(0u, 200) {
- assert_eq!(v.borrow().as_slice()[i], 1);
- }
- drop(v);
-
- for i in range(0u, 50) {
- let k = Dropable::new(i);
- let v = m.pop(&k);
-
- assert!(v.is_some());
-
- let v = drop_vector.get().unwrap();
- assert_eq!(v.borrow().as_slice()[i], 1);
- assert_eq!(v.borrow().as_slice()[i+100], 1);
- }
-
- let v = drop_vector.get().unwrap();
- for i in range(0u, 50) {
- assert_eq!(v.borrow().as_slice()[i], 0);
- assert_eq!(v.borrow().as_slice()[i+100], 0);
- }
-
- for i in range(50u, 100) {
- assert_eq!(v.borrow().as_slice()[i], 1);
- assert_eq!(v.borrow().as_slice()[i+100], 1);
- }
- }
-
- let v = drop_vector.get().unwrap();
- for i in range(0u, 200) {
- assert_eq!(v.borrow().as_slice()[i], 0);
- }
- }
-
- #[test]
- fn test_move_iter_drops() {
- drop_vector.replace(Some(RefCell::new(Vec::from_elem(200, 0i))));
-
- let hm = {
- let mut hm = HashMap::new();
-
- let v = drop_vector.get().unwrap();
- for i in range(0u, 200) {
- assert_eq!(v.borrow().as_slice()[i], 0);
- }
- drop(v);
-
- for i in range(0u, 100) {
- let d1 = Dropable::new(i);
- let d2 = Dropable::new(i+100);
- hm.insert(d1, d2);
- }
-
- let v = drop_vector.get().unwrap();
- for i in range(0u, 200) {
- assert_eq!(v.borrow().as_slice()[i], 1);
- }
- drop(v);
-
- hm
- };
-
- // By the way, ensure that cloning doesn't screw up the dropping.
- drop(hm.clone());
-
- {
- let mut half = hm.into_iter().take(50);
-
- let v = drop_vector.get().unwrap();
- for i in range(0u, 200) {
- assert_eq!(v.borrow().as_slice()[i], 1);
- }
- drop(v);
-
- for _ in half {}
-
- let v = drop_vector.get().unwrap();
- let nk = range(0u, 100).filter(|&i| {
- v.borrow().as_slice()[i] == 1
- }).count();
-
- let nv = range(0u, 100).filter(|&i| {
- v.borrow().as_slice()[i+100] == 1
- }).count();
-
- assert_eq!(nk, 50);
- assert_eq!(nv, 50);
- };
-
- let v = drop_vector.get().unwrap();
- for i in range(0u, 200) {
- assert_eq!(v.borrow().as_slice()[i], 0);
- }
- }
-
- #[test]
- fn test_empty_pop() {
- let mut m: HashMap<int, bool> = HashMap::new();
- assert_eq!(m.pop(&0), None);
- }
-
- #[test]
- fn test_lots_of_insertions() {
- let mut m = HashMap::new();
-
- // Try this a few times to make sure we never screw up the hashmap's
- // internal state.
- for _ in range(0i, 10) {
- assert!(m.is_empty());
-
- for i in range_inclusive(1i, 1000) {
- assert!(m.insert(i, i));
-
- for j in range_inclusive(1, i) {
- let r = m.find(&j);
- assert_eq!(r, Some(&j));
- }
-
- for j in range_inclusive(i+1, 1000) {
- let r = m.find(&j);
- assert_eq!(r, None);
- }
- }
-
- for i in range_inclusive(1001i, 2000) {
- assert!(!m.contains_key(&i));
- }
-
- // remove forwards
- for i in range_inclusive(1i, 1000) {
- assert!(m.remove(&i));
-
- for j in range_inclusive(1, i) {
- assert!(!m.contains_key(&j));
- }
-
- for j in range_inclusive(i+1, 1000) {
- assert!(m.contains_key(&j));
- }
- }
-
- for i in range_inclusive(1i, 1000) {
- assert!(!m.contains_key(&i));
- }
-
- for i in range_inclusive(1i, 1000) {
- assert!(m.insert(i, i));
- }
-
- // remove backwards
- for i in range_step_inclusive(1000i, 1, -1) {
- assert!(m.remove(&i));
-
- for j in range_inclusive(i, 1000) {
- assert!(!m.contains_key(&j));
- }
-
- for j in range_inclusive(1, i-1) {
- assert!(m.contains_key(&j));
- }
- }
- }
- }
-
- #[test]
- fn test_find_mut() {
- let mut m = HashMap::new();
- assert!(m.insert(1i, 12i));
- assert!(m.insert(2i, 8i));
- assert!(m.insert(5i, 14i));
- let new = 100;
- match m.find_mut(&5) {
- None => panic!(), Some(x) => *x = new
- }
- assert_eq!(m.find(&5), Some(&new));
- }
-
- #[test]
- fn test_insert_overwrite() {
- let mut m = HashMap::new();
- assert!(m.insert(1i, 2i));
- assert_eq!(*m.find(&1).unwrap(), 2);
- assert!(!m.insert(1i, 3i));
- assert_eq!(*m.find(&1).unwrap(), 3);
- }
-
- #[test]
- fn test_insert_conflicts() {
- let mut m = HashMap::with_capacity(4);
- assert!(m.insert(1i, 2i));
- assert!(m.insert(5i, 3i));
- assert!(m.insert(9i, 4i));
- assert_eq!(*m.find(&9).unwrap(), 4);
- assert_eq!(*m.find(&5).unwrap(), 3);
- assert_eq!(*m.find(&1).unwrap(), 2);
- }
-
- #[test]
- fn test_conflict_remove() {
- let mut m = HashMap::with_capacity(4);
- assert!(m.insert(1i, 2i));
- assert_eq!(*m.find(&1).unwrap(), 2);
- assert!(m.insert(5, 3));
- assert_eq!(*m.find(&1).unwrap(), 2);
- assert_eq!(*m.find(&5).unwrap(), 3);
- assert!(m.insert(9, 4));
- assert_eq!(*m.find(&1).unwrap(), 2);
- assert_eq!(*m.find(&5).unwrap(), 3);
- assert_eq!(*m.find(&9).unwrap(), 4);
- assert!(m.remove(&1));
- assert_eq!(*m.find(&9).unwrap(), 4);
- assert_eq!(*m.find(&5).unwrap(), 3);
- }
-
- #[test]
- fn test_is_empty() {
- let mut m = HashMap::with_capacity(4);
- assert!(m.insert(1i, 2i));
- assert!(!m.is_empty());
- assert!(m.remove(&1));
- assert!(m.is_empty());
- }
-
- #[test]
- fn test_pop() {
- let mut m = HashMap::new();
- m.insert(1i, 2i);
- assert_eq!(m.pop(&1), Some(2));
- assert_eq!(m.pop(&1), None);
- }
-
- #[test]
- #[allow(experimental)]
- fn test_pop_equiv() {
- let mut m = HashMap::new();
- m.insert(1i, 2i);
- assert_eq!(m.pop_equiv(&KindaIntLike(1)), Some(2));
- assert_eq!(m.pop_equiv(&KindaIntLike(1)), None);
- }
-
- #[test]
- fn test_swap() {
- let mut m = HashMap::new();
- assert_eq!(m.swap(1i, 2i), None);
- assert_eq!(m.swap(1i, 3i), Some(2));
- assert_eq!(m.swap(1i, 4i), Some(3));
- }
-
- #[test]
- fn test_iterate() {
- let mut m = HashMap::with_capacity(4);
- for i in range(0u, 32) {
- assert!(m.insert(i, i*2));
- }
- assert_eq!(m.len(), 32);
-
- let mut observed: u32 = 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 = vec![(1i, 'a'), (2i, 'b'), (3i, 'c')];
- let map = vec.into_iter().collect::<HashMap<int, char>>();
- let keys = map.keys().map(|&k| k).collect::<Vec<int>>();
- assert_eq!(keys.len(), 3);
- assert!(keys.contains(&1));
- assert!(keys.contains(&2));
- assert!(keys.contains(&3));
- }
-
- #[test]
- fn test_values() {
- let vec = vec![(1i, 'a'), (2i, 'b'), (3i, 'c')];
- let map = vec.into_iter().collect::<HashMap<int, char>>();
- let values = map.values().map(|&v| v).collect::<Vec<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(&1i).is_none());
- m.insert(1i, 2i);
- match m.find(&1) {
- None => panic!(),
- Some(v) => assert_eq!(*v, 2)
- }
- }
-
- #[test]
- fn test_find_copy() {
- let mut m = HashMap::new();
- assert!(m.find(&1i).is_none());
-
- for i in range(1i, 10000) {
- m.insert(i, i + 7);
- match m.find_copy(&i) {
- None => panic!(),
- Some(v) => assert_eq!(v, i + 7)
- }
- for j in range(1i, i/100) {
- match m.find_copy(&j) {
- None => panic!(),
- Some(v) => assert_eq!(v, j + 7)
- }
- }
- }
- }
-
- #[test]
- fn test_eq() {
- let mut m1 = HashMap::new();
- m1.insert(1i, 2i);
- m1.insert(2i, 3i);
- m1.insert(3i, 4i);
-
- let mut m2 = HashMap::new();
- m2.insert(1i, 2i);
- m2.insert(2i, 3i);
-
- assert!(m1 != m2);
-
- m2.insert(3i, 4i);
-
- assert_eq!(m1, m2);
- }
-
- #[test]
- fn test_show() {
- let mut map: HashMap<int, int> = HashMap::new();
- let empty: HashMap<int, int> = HashMap::new();
-
- map.insert(1i, 2i);
- map.insert(3i, 4i);
-
- let map_str = format!("{}", map);
-
- assert!(map_str == "{1: 2, 3: 4}".to_string() || map_str == "{3: 4, 1: 2}".to_string());
- assert_eq!(format!("{}", empty), "{}".to_string());
- }
-
- #[test]
- fn test_expand() {
- let mut m = HashMap::new();
-
- assert_eq!(m.len(), 0);
- assert!(m.is_empty());
-
- let mut i = 0u;
- let old_cap = m.table.capacity();
- while old_cap == m.table.capacity() {
- m.insert(i, i);
- i += 1;
- }
-
- assert_eq!(m.len(), i);
- assert!(!m.is_empty());
- }
-
- #[test]
- fn test_resize_policy() {
- let mut m = HashMap::new();
-
- assert_eq!(m.len(), 0);
- assert_eq!(m.table.capacity(), 0);
- assert!(m.is_empty());
-
- m.insert(0, 0);
- m.remove(&0);
- assert!(m.is_empty());
- let initial_cap = m.table.capacity();
- m.reserve(initial_cap * 2);
- let cap = m.table.capacity();
-
- assert_eq!(cap, initial_cap * 2);
-
- let mut i = 0u;
- for _ in range(0, cap * 3 / 4) {
- m.insert(i, i);
- i += 1;
- }
- // three quarters full
-
- assert_eq!(m.len(), i);
- assert_eq!(m.table.capacity(), cap);
-
- for _ in range(0, cap / 4) {
- m.insert(i, i);
- i += 1;
- }
- // half full
-
- let new_cap = m.table.capacity();
- assert_eq!(new_cap, cap * 2);
-
- for _ in range(0, cap / 2 - 1) {
- i -= 1;
- m.remove(&i);
- assert_eq!(m.table.capacity(), new_cap);
- }
- // A little more than one quarter full.
- // Shrinking starts as we remove more elements:
- for _ in range(0, cap / 2 - 1) {
- i -= 1;
- m.remove(&i);
- }
-
- assert_eq!(m.len(), i);
- assert!(!m.is_empty());
- assert_eq!(m.table.capacity(), cap);
- }
-
- #[test]
- fn test_find_equiv() {
- let mut m = HashMap::new();
-
- let (foo, bar, baz) = (1i,2i,3i);
- m.insert("foo".to_string(), foo);
- m.insert("bar".to_string(), bar);
- m.insert("baz".to_string(), 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 = [(1i, 1i), (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));
- }
- }
-
- #[test]
- fn test_size_hint() {
- let xs = [(1i, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
- let map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
-
- let mut iter = map.iter();
-
- for _ in iter.by_ref().take(3) {}
-
- assert_eq!(iter.size_hint(), (3, Some(3)));
- }
-
- #[test]
- fn test_mut_size_hint() {
- let xs = [(1i, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
- let mut map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
-
- let mut iter = map.iter_mut();
-
- for _ in iter.by_ref().take(3) {}
-
- assert_eq!(iter.size_hint(), (3, Some(3)));
- }
-
- #[test]
- fn test_index() {
- let mut map: HashMap<int, int> = HashMap::new();
-
- map.insert(1, 2);
- map.insert(2, 1);
- map.insert(3, 4);
-
- assert_eq!(map[2], 1);
- }
-
- #[test]
- #[should_fail]
- fn test_index_nonexistent() {
- let mut map: HashMap<int, int> = HashMap::new();
-
- map.insert(1, 2);
- map.insert(2, 1);
- map.insert(3, 4);
-
- map[4];
- }
-
- #[test]
- fn test_entry(){
- let xs = [(1i, 10i), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
-
- let mut map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
-
- // Existing key (insert)
- match map.entry(1) {
- Vacant(_) => unreachable!(),
- Occupied(mut view) => {
- assert_eq!(view.get(), &10);
- assert_eq!(view.set(100), 10);
- }
- }
- assert_eq!(map.find(&1).unwrap(), &100);
- assert_eq!(map.len(), 6);
-
-
- // Existing key (update)
- match map.entry(2) {
- Vacant(_) => unreachable!(),
- Occupied(mut view) => {
- let v = view.get_mut();
- let new_v = (*v) * 10;
- *v = new_v;
- }
- }
- assert_eq!(map.find(&2).unwrap(), &200);
- assert_eq!(map.len(), 6);
-
- // Existing key (take)
- match map.entry(3) {
- Vacant(_) => unreachable!(),
- Occupied(view) => {
- assert_eq!(view.take(), 30);
- }
- }
- assert_eq!(map.find(&3), None);
- assert_eq!(map.len(), 5);
-
-
- // Inexistent key (insert)
- match map.entry(10) {
- Occupied(_) => unreachable!(),
- Vacant(view) => {
- assert_eq!(*view.set(1000), 1000);
- }
- }
- assert_eq!(map.find(&10).unwrap(), &1000);
- assert_eq!(map.len(), 6);
- }
-}
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <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
-
-pub use self::map::HashMap;
-pub use self::map::Entries;
-pub use self::map::MutEntries;
-pub use self::map::MoveEntries;
-pub use self::map::Entry;
-pub use self::map::Occupied;
-pub use self::map::Vacant;
-pub use self::map::OccupiedEntry;
-pub use self::map::VacantEntry;
-pub use self::map::Keys;
-pub use self::map::Values;
-pub use self::map::INITIAL_CAPACITY;
-pub use self::set::HashSet;
-pub use self::set::SetItems;
-pub use self::set::SetMoveItems;
-pub use self::set::SetAlgebraItems;
-
-mod bench;
-mod map;
-mod set;
-mod table;
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <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.
-//
-// ignore-lexer-test FIXME #15883
-
-use clone::Clone;
-use cmp::{Eq, Equiv, PartialEq};
-use core::kinds::Sized;
-use default::Default;
-use fmt::Show;
-use fmt;
-use hash::{Hash, Hasher, RandomSipHasher};
-use iter::{Iterator, FromIterator, FilterMap, Chain, Repeat, Zip, Extendable};
-use iter;
-use option::{Some, None};
-use result::{Ok, Err};
-
-use super::{HashMap, Entries, MoveEntries, INITIAL_CAPACITY};
-
-
-// Future Optimization (FIXME!)
-// =============================
-//
-// Iteration over zero sized values is a noop. There is no need
-// for `bucket.val` in the case of HashSet. I suppose we would need HKT
-// to get rid of it properly.
-
-/// 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.
-///
-/// # Example
-///
-/// ```
-/// use std::collections::HashSet;
-/// // Type inference lets us omit an explicit type signature (which
-/// // would be `HashSet<&str>` in this example).
-/// let mut books = HashSet::new();
-///
-/// // Add some books.
-/// books.insert("A Dance With Dragons");
-/// books.insert("To Kill a Mockingbird");
-/// books.insert("The Odyssey");
-/// books.insert("The Great Gatsby");
-///
-/// // Check for a specific one.
-/// if !books.contains(&("The Winds of Winter")) {
-/// println!("We have {} books, but The Winds of Winter ain't one.",
-/// books.len());
-/// }
-///
-/// // Remove a book.
-/// books.remove(&"The Odyssey");
-///
-/// // Iterate over everything.
-/// for book in books.iter() {
-/// println!("{}", *book);
-/// }
-/// ```
-///
-/// The easiest way to use `HashSet` with a custom type is to derive
-/// `Eq` and `Hash`. We must also derive `PartialEq`, this will in the
-/// future be implied by `Eq`.
-///
-/// ```
-/// use std::collections::HashSet;
-/// #[deriving(Hash, Eq, PartialEq, Show)]
-/// struct Viking<'a> {
-/// name: &'a str,
-/// power: uint,
-/// }
-///
-/// let mut vikings = HashSet::new();
-///
-/// vikings.insert(Viking { name: "Einar", power: 9u });
-/// vikings.insert(Viking { name: "Einar", power: 9u });
-/// vikings.insert(Viking { name: "Olaf", power: 4u });
-/// vikings.insert(Viking { name: "Harald", power: 8u });
-///
-/// // Use derived implementation to print the vikings.
-/// for x in vikings.iter() {
-/// println!("{}", x);
-/// }
-/// ```
-#[deriving(Clone)]
-pub struct HashSet<T, H = RandomSipHasher> {
- map: HashMap<T, (), H>
-}
-
-impl<T: Hash + Eq> HashSet<T, RandomSipHasher> {
- /// Create an empty HashSet.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- /// let mut set: HashSet<int> = HashSet::new();
- /// ```
- #[inline]
- pub fn new() -> HashSet<T, RandomSipHasher> {
- HashSet::with_capacity(INITIAL_CAPACITY)
- }
-
- /// Create an empty HashSet with space for at least `n` elements in
- /// the hash table.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- /// let mut set: HashSet<int> = HashSet::with_capacity(10);
- /// ```
- #[inline]
- pub fn with_capacity(capacity: uint) -> HashSet<T, RandomSipHasher> {
- HashSet { map: HashMap::with_capacity(capacity) }
- }
-}
-
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
- /// Creates a new empty hash set which will use the given hasher to hash
- /// keys.
- ///
- /// The hash set is also created with the default initial capacity.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- /// use std::hash::sip::SipHasher;
- ///
- /// let h = SipHasher::new();
- /// let mut set = HashSet::with_hasher(h);
- /// set.insert(2u);
- /// ```
- #[inline]
- pub fn with_hasher(hasher: H) -> HashSet<T, H> {
- HashSet::with_capacity_and_hasher(INITIAL_CAPACITY, hasher)
- }
-
- /// Create an empty HashSet with space for at least `capacity`
- /// elements in the hash table, using `hasher` to hash the keys.
- ///
- /// Warning: `hasher` is normally randomly generated, and
- /// is designed to allow `HashSet`s to be resistant to attacks that
- /// cause many collisions and very poor performance. Setting it
- /// manually using this function can expose a DoS attack vector.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- /// use std::hash::sip::SipHasher;
- ///
- /// let h = SipHasher::new();
- /// let mut set = HashSet::with_capacity_and_hasher(10u, h);
- /// set.insert(1i);
- /// ```
- #[inline]
- pub fn with_capacity_and_hasher(capacity: uint, hasher: H) -> HashSet<T, H> {
- HashSet { map: HashMap::with_capacity_and_hasher(capacity, hasher) }
- }
-
- /// Reserve space for at least `n` elements in the hash table.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- /// let mut set: HashSet<int> = HashSet::new();
- /// set.reserve(10);
- /// ```
- 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.
- ///
- /// # Example
- ///
- /// This is a slightly silly example where we define the number's
- /// parity as the equivalance class. It is important that the
- /// values hash the same, which is why we implement `Hash`.
- ///
- /// ```
- /// use std::collections::HashSet;
- /// use std::hash::Hash;
- /// use std::hash::sip::SipState;
- ///
- /// #[deriving(Eq, PartialEq)]
- /// struct EvenOrOdd {
- /// num: uint
- /// };
- ///
- /// impl Hash for EvenOrOdd {
- /// fn hash(&self, state: &mut SipState) {
- /// let parity = self.num % 2;
- /// parity.hash(state);
- /// }
- /// }
- ///
- /// impl Equiv<EvenOrOdd> for EvenOrOdd {
- /// fn equiv(&self, other: &EvenOrOdd) -> bool {
- /// self.num % 2 == other.num % 2
- /// }
- /// }
- ///
- /// let mut set = HashSet::new();
- /// set.insert(EvenOrOdd { num: 3u });
- ///
- /// assert!(set.contains_equiv(&EvenOrOdd { num: 3u }));
- /// assert!(set.contains_equiv(&EvenOrOdd { num: 5u }));
- /// assert!(!set.contains_equiv(&EvenOrOdd { num: 4u }));
- /// assert!(!set.contains_equiv(&EvenOrOdd { num: 2u }));
- ///
- /// ```
- pub fn contains_equiv<Sized? Q: Hash<S> + 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.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- /// let mut set = HashSet::new();
- /// set.insert("a");
- /// set.insert("b");
- ///
- /// // Will print in an arbitrary order.
- /// for x in set.iter() {
- /// println!("{}", x);
- /// }
- /// ```
- pub fn iter<'a>(&'a self) -> SetItems<'a, T> {
- self.map.keys()
- }
-
- /// Deprecated: use `into_iter`.
- #[deprecated = "use into_iter"]
- pub fn move_iter(self) -> SetMoveItems<T> {
- self.into_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.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- /// let mut set = HashSet::new();
- /// set.insert("a".to_string());
- /// set.insert("b".to_string());
- ///
- /// // Not possible to collect to a Vec<String> with a regular `.iter()`.
- /// let v: Vec<String> = set.into_iter().collect();
- ///
- /// // Will print in an arbitrary order.
- /// for x in v.iter() {
- /// println!("{}", x);
- /// }
- /// ```
- pub fn into_iter(self) -> SetMoveItems<T> {
- self.map.into_iter().map(|(k, _)| k)
- }
-
- /// Visit the values representing the difference.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
- /// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
- ///
- /// // Can be seen as `a - b`.
- /// for x in a.difference(&b) {
- /// println!("{}", x); // Print 1
- /// }
- ///
- /// let diff: HashSet<int> = a.difference(&b).map(|&x| x).collect();
- /// assert_eq!(diff, [1i].iter().map(|&x| x).collect());
- ///
- /// // Note that difference is not symmetric,
- /// // and `b - a` means something else:
- /// let diff: HashSet<int> = b.difference(&a).map(|&x| x).collect();
- /// assert_eq!(diff, [4i].iter().map(|&x| x).collect());
- /// ```
- pub fn difference<'a>(&'a self, other: &'a HashSet<T, H>) -> SetAlgebraItems<'a, T, H> {
- 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.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
- /// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
- ///
- /// // Print 1, 4 in arbitrary order.
- /// for x in a.symmetric_difference(&b) {
- /// println!("{}", x);
- /// }
- ///
- /// let diff1: HashSet<int> = a.symmetric_difference(&b).map(|&x| x).collect();
- /// let diff2: HashSet<int> = b.symmetric_difference(&a).map(|&x| x).collect();
- ///
- /// assert_eq!(diff1, diff2);
- /// assert_eq!(diff1, [1i, 4].iter().map(|&x| x).collect());
- /// ```
- pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet<T, H>)
- -> Chain<SetAlgebraItems<'a, T, H>, SetAlgebraItems<'a, T, H>> {
- self.difference(other).chain(other.difference(self))
- }
-
- /// Visit the values representing the intersection.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
- /// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
- ///
- /// // Print 2, 3 in arbitrary order.
- /// for x in a.intersection(&b) {
- /// println!("{}", x);
- /// }
- ///
- /// let diff: HashSet<int> = a.intersection(&b).map(|&x| x).collect();
- /// assert_eq!(diff, [2i, 3].iter().map(|&x| x).collect());
- /// ```
- pub fn intersection<'a>(&'a self, other: &'a HashSet<T, H>)
- -> SetAlgebraItems<'a, T, H> {
- Repeat::new(other).zip(self.iter())
- .filter_map(|(other, elt)| {
- if other.contains(elt) { Some(elt) } else { None }
- })
- }
-
- /// Visit the values representing the union.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
- /// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
- ///
- /// // Print 1, 2, 3, 4 in arbitrary order.
- /// for x in a.union(&b) {
- /// println!("{}", x);
- /// }
- ///
- /// let diff: HashSet<int> = a.union(&b).map(|&x| x).collect();
- /// assert_eq!(diff, [1i, 2, 3, 4].iter().map(|&x| x).collect());
- /// ```
- pub fn union<'a>(&'a self, other: &'a HashSet<T, H>)
- -> Chain<SetItems<'a, T>, SetAlgebraItems<'a, T, H>> {
- self.iter().chain(other.difference(self))
- }
-
- /// Return the number of elements in the set
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- ///
- /// let mut v = HashSet::new();
- /// assert_eq!(v.len(), 0);
- /// v.insert(1u);
- /// assert_eq!(v.len(), 1);
- /// ```
- pub fn len(&self) -> uint { self.map.len() }
-
- /// Returns true if the set contains no elements
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- ///
- /// let mut v = HashSet::new();
- /// assert!(v.is_empty());
- /// v.insert(1u);
- /// assert!(!v.is_empty());
- /// ```
- pub fn is_empty(&self) -> bool { self.map.len() == 0 }
-
- /// Clears the set, removing all values.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- ///
- /// let mut v = HashSet::new();
- /// v.insert(1u);
- /// v.clear();
- /// assert!(v.is_empty());
- /// ```
- pub fn clear(&mut self) { self.map.clear() }
-
- /// Returns `true` if the set contains a value.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- ///
- /// let set: HashSet<uint> = [1, 2, 3].iter().map(|&x| x).collect();
- /// assert_eq!(set.contains(&1), true);
- /// assert_eq!(set.contains(&4), false);
- /// ```
- pub fn contains(&self, value: &T) -> bool { self.map.contains_key(value) }
-
- /// Returns `true` if the set has no elements in common with `other`.
- /// This is equivalent to checking for an empty intersection.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- ///
- /// let a: HashSet<uint> = [1, 2, 3].iter().map(|&x| x).collect();
- /// let mut b: HashSet<uint> = HashSet::new();
- ///
- /// assert_eq!(a.is_disjoint(&b), true);
- /// b.insert(4);
- /// assert_eq!(a.is_disjoint(&b), true);
- /// b.insert(1);
- /// assert_eq!(a.is_disjoint(&b), false);
- /// ```
- pub fn is_disjoint(&self, other: &HashSet<T, H>) -> bool {
- self.iter().all(|v| !other.contains(v))
- }
-
- /// Returns `true` if the set is a subset of another.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- ///
- /// let sup: HashSet<uint> = [1, 2, 3].iter().map(|&x| x).collect();
- /// let mut set: HashSet<uint> = HashSet::new();
- ///
- /// assert_eq!(set.is_subset(&sup), true);
- /// set.insert(2);
- /// assert_eq!(set.is_subset(&sup), true);
- /// set.insert(4);
- /// assert_eq!(set.is_subset(&sup), false);
- /// ```
- pub fn is_subset(&self, other: &HashSet<T, H>) -> bool {
- self.iter().all(|v| other.contains(v))
- }
-
- /// Returns `true` if the set is a superset of another.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- ///
- /// let sub: HashSet<uint> = [1, 2].iter().map(|&x| x).collect();
- /// let mut set: HashSet<uint> = HashSet::new();
- ///
- /// assert_eq!(set.is_superset(&sub), false);
- ///
- /// set.insert(0);
- /// set.insert(1);
- /// assert_eq!(set.is_superset(&sub), false);
- ///
- /// set.insert(2);
- /// assert_eq!(set.is_superset(&sub), true);
- /// ```
- #[inline]
- pub fn is_superset(&self, other: &HashSet<T, H>) -> bool {
- other.is_subset(self)
- }
-
- /// Adds a value to the set. Returns `true` if the value was not already
- /// present in the set.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- ///
- /// let mut set = HashSet::new();
- ///
- /// assert_eq!(set.insert(2u), true);
- /// assert_eq!(set.insert(2), false);
- /// assert_eq!(set.len(), 1);
- /// ```
- pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
-
- /// Removes a value from the set. Returns `true` if the value was
- /// present in the set.
- ///
- /// # Example
- ///
- /// ```
- /// use std::collections::HashSet;
- ///
- /// let mut set = HashSet::new();
- ///
- /// set.insert(2u);
- /// assert_eq!(set.remove(&2), true);
- /// assert_eq!(set.remove(&2), false);
- /// ```
- pub fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
-}
-
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> PartialEq for HashSet<T, H> {
- fn eq(&self, other: &HashSet<T, H>) -> bool {
- if self.len() != other.len() { return false; }
-
- self.iter().all(|key| other.contains(key))
- }
-}
-
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> Eq for HashSet<T, H> {}
-
-impl<T: Eq + Hash<S> + fmt::Show, S, H: Hasher<S>> fmt::Show for HashSet<T, H> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- try!(write!(f, "{{"));
-
- for (i, x) in self.iter().enumerate() {
- if i != 0 { try!(write!(f, ", ")); }
- try!(write!(f, "{}", *x));
- }
-
- write!(f, "}}")
- }
-}
-
-impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> FromIterator<T> for HashSet<T, H> {
- fn from_iter<I: Iterator<T>>(iter: I) -> HashSet<T, H> {
- let (lower, _) = iter.size_hint();
- let mut set = HashSet::with_capacity_and_hasher(lower, Default::default());
- set.extend(iter);
- set
- }
-}
-
-impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> Extendable<T> for HashSet<T, H> {
- fn extend<I: Iterator<T>>(&mut self, mut iter: I) {
- for k in iter {
- self.insert(k);
- }
- }
-}
-
-impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> Default for HashSet<T, H> {
- fn default() -> HashSet<T, H> {
- HashSet::with_hasher(Default::default())
- }
-}
-
-/// HashSet iterator
-pub type SetItems<'a, K> =
- iter::Map<'static, (&'a K, &'a ()), &'a K, Entries<'a, K, ()>>;
-
-/// HashSet move iterator
-pub type SetMoveItems<K> =
- iter::Map<'static, (K, ()), K, MoveEntries<K, ()>>;
-
-// `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, H> =
- FilterMap<'static, (&'a HashSet<T, H>, &'a T), &'a T,
- Zip<Repeat<&'a HashSet<T, H>>, SetItems<'a, T>>>;
-
-#[cfg(test)]
-mod test_set {
- use prelude::*;
-
- use super::HashSet;
- use slice::ImmutablePartialEqSlice;
-
- #[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(5i));
- assert!(ys.insert(11i));
- assert!(xs.is_disjoint(&ys));
- assert!(ys.is_disjoint(&xs));
- assert!(xs.insert(7));
- assert!(xs.insert(19));
- assert!(xs.insert(4));
- assert!(ys.insert(2));
- assert!(ys.insert(-11));
- assert!(xs.is_disjoint(&ys));
- assert!(ys.is_disjoint(&xs));
- assert!(ys.insert(7));
- assert!(!xs.is_disjoint(&ys));
- assert!(!ys.is_disjoint(&xs));
- }
-
- #[test]
- fn test_subset_and_superset() {
- let mut a = HashSet::new();
- assert!(a.insert(0i));
- assert!(a.insert(5));
- assert!(a.insert(11));
- assert!(a.insert(7));
-
- let mut b = HashSet::new();
- assert!(b.insert(0i));
- assert!(b.insert(7));
- assert!(b.insert(19));
- assert!(b.insert(250));
- assert!(b.insert(11));
- assert!(b.insert(200));
-
- assert!(!a.is_subset(&b));
- assert!(!a.is_superset(&b));
- assert!(!b.is_subset(&a));
- assert!(!b.is_superset(&a));
-
- assert!(b.insert(5));
-
- assert!(a.is_subset(&b));
- assert!(!a.is_superset(&b));
- assert!(!b.is_subset(&a));
- assert!(b.is_superset(&a));
- }
-
- #[test]
- fn test_iterate() {
- let mut a = HashSet::new();
- for i in range(0u, 32) {
- assert!(a.insert(i));
- }
- let mut observed: u32 = 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(11i));
- 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(2i));
- 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(1i));
- assert!(a.insert(3));
- assert!(a.insert(5));
- assert!(a.insert(9));
- assert!(a.insert(11));
-
- assert!(b.insert(3i));
- 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(1i));
- assert!(a.insert(3));
- assert!(a.insert(5));
- assert!(a.insert(9));
- assert!(a.insert(11));
-
- assert!(b.insert(-2i));
- 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(1i));
- 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(-2i));
- 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 = [1i, 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.into_iter().collect::<Vec<char>>();
- assert!(['a', 'b'] == v.as_slice() || ['b', 'a'] == v.as_slice());
- }
-
- #[test]
- fn test_eq() {
- // These constants once happened to expose a bug in insert().
- // I'm keeping them around to prevent a regression.
- let mut s1 = HashSet::new();
-
- s1.insert(1i);
- s1.insert(2);
- s1.insert(3);
-
- let mut s2 = HashSet::new();
-
- s2.insert(1i);
- 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(1i);
- set.insert(2);
-
- let set_str = format!("{}", set);
-
- assert!(set_str == "{1, 2}".to_string() || set_str == "{2, 1}".to_string());
- assert_eq!(format!("{}", empty), "{}".to_string());
- }
-}
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <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.
-//
-// ignore-lexer-test FIXME #15883
-
-use clone::Clone;
-use cmp;
-use hash::{Hash, Hasher};
-use iter::{Iterator, count};
-use kinds::{Sized, marker};
-use mem::{min_align_of, size_of};
-use mem;
-use num::{CheckedAdd, CheckedMul, is_power_of_two};
-use ops::{Deref, DerefMut, Drop};
-use option::{Some, None, Option};
-use ptr::{RawPtr, copy_nonoverlapping_memory, zero_memory};
-use ptr;
-use rt::heap::{allocate, deallocate};
-
-const EMPTY_BUCKET: u64 = 0u64;
-
-/// The raw hashtable, providing safe-ish access to the unzipped and highly
-/// optimized arrays of hashes, keys, and values.
-///
-/// This design uses less memory and is a lot faster than the naive
-/// `Vec<Option<u64, K, V>>`, because we don't pay for the overhead of an
-/// option on every element, and we get a generally more cache-aware design.
-///
-/// Essential invariants of this structure:
-///
-/// - if t.hashes[i] == EMPTY_BUCKET, then `Bucket::at_index(&t, i).raw`
-/// points to 'undefined' contents. Don't read from it. This invariant is
-/// enforced outside this module with the `EmptyBucket`, `FullBucket`,
-/// and `SafeHash` types.
-///
-/// - An `EmptyBucket` is only constructed at an index with
-/// a hash of EMPTY_BUCKET.
-///
-/// - A `FullBucket` is only constructed at an index with a
-/// non-EMPTY_BUCKET hash.
-///
-/// - A `SafeHash` is only constructed for non-`EMPTY_BUCKET` hash. We get
-/// around hashes of zero by changing them to 0x8000_0000_0000_0000,
-/// which will likely map to the same bucket, while not being confused
-/// with "empty".
-///
-/// - All three "arrays represented by pointers" are the same length:
-/// `capacity`. This is set at creation and never changes. The arrays
-/// are unzipped to save space (we don't have to pay for the padding
-/// between odd sized elements, such as in a map from u64 to u8), and
-/// be more cache aware (scanning through 8 hashes brings in at most
-/// 2 cache lines, since they're all right beside each other).
-///
-/// You can kind of think of this module/data structure as a safe wrapper
-/// around just the "table" part of the hashtable. It enforces some
-/// invariants at the type level and employs some performance trickery,
-/// but in general is just a tricked out `Vec<Option<u64, K, V>>`.
-#[unsafe_no_drop_flag]
-pub struct RawTable<K, V> {
- capacity: uint,
- size: uint,
- hashes: *mut u64,
- // Because K/V do not appear directly in any of the types in the struct,
- // inform rustc that in fact instances of K and V are reachable from here.
- marker: marker::CovariantType<(K,V)>,
-}
-
-struct RawBucket<K, V> {
- hash: *mut u64,
- key: *mut K,
- val: *mut V
-}
-
-pub struct Bucket<K, V, M> {
- raw: RawBucket<K, V>,
- idx: uint,
- table: M
-}
-
-pub struct EmptyBucket<K, V, M> {
- raw: RawBucket<K, V>,
- idx: uint,
- table: M
-}
-
-pub struct FullBucket<K, V, M> {
- raw: RawBucket<K, V>,
- idx: uint,
- table: M
-}
-
-pub type EmptyBucketImm<'table, K, V> = EmptyBucket<K, V, &'table RawTable<K, V>>;
-pub type FullBucketImm<'table, K, V> = FullBucket<K, V, &'table RawTable<K, V>>;
-
-pub type EmptyBucketMut<'table, K, V> = EmptyBucket<K, V, &'table mut RawTable<K, V>>;
-pub type FullBucketMut<'table, K, V> = FullBucket<K, V, &'table mut RawTable<K, V>>;
-
-pub enum BucketState<K, V, M> {
- Empty(EmptyBucket<K, V, M>),
- Full(FullBucket<K, V, M>),
-}
-
-// A GapThenFull encapsulates the state of two consecutive buckets at once.
-// The first bucket, called the gap, is known to be empty.
-// The second bucket is full.
-struct GapThenFull<K, V, M> {
- gap: EmptyBucket<K, V, ()>,
- full: FullBucket<K, V, M>,
-}
-
-/// A hash that is not zero, since we use a hash of zero to represent empty
-/// buckets.
-#[deriving(PartialEq)]
-pub struct SafeHash {
- hash: u64,
-}
-
-impl SafeHash {
- /// Peek at the hash value, which is guaranteed to be non-zero.
- #[inline(always)]
- pub fn inspect(&self) -> u64 { self.hash }
-}
-
-/// We need to remove hashes of 0. That's reserved for empty buckets.
-/// This function wraps up `hash_keyed` to be the only way outside this
-/// module to generate a SafeHash.
-pub fn make_hash<Sized? T: Hash<S>, S, H: Hasher<S>>(hasher: &H, t: &T) -> SafeHash {
- match hasher.hash(t) {
- // This constant is exceedingly likely to hash to the same
- // bucket, but it won't be counted as empty! Just so we can maintain
- // our precious uniform distribution of initial indexes.
- EMPTY_BUCKET => SafeHash { hash: 0x8000_0000_0000_0000 },
- h => SafeHash { hash: h },
- }
-}
-
-// `replace` casts a `*u64` to a `*SafeHash`. Since we statically
-// ensure that a `FullBucket` points to an index with a non-zero hash,
-// and a `SafeHash` is just a `u64` with a different name, this is
-// safe.
-//
-// This test ensures that a `SafeHash` really IS the same size as a
-// `u64`. If you need to change the size of `SafeHash` (and
-// consequently made this test fail), `replace` needs to be
-// modified to no longer assume this.
-#[test]
-fn can_alias_safehash_as_u64() {
- assert_eq!(size_of::<SafeHash>(), size_of::<u64>())
-}
-
-impl<K, V> RawBucket<K, V> {
- unsafe fn offset(self, count: int) -> RawBucket<K, V> {
- RawBucket {
- hash: self.hash.offset(count),
- key: self.key.offset(count),
- val: self.val.offset(count),
- }
- }
-}
-
-// For parameterizing over mutability.
-impl<'t, K, V> Deref<RawTable<K, V>> for &'t RawTable<K, V> {
- fn deref(&self) -> &RawTable<K, V> {
- &**self
- }
-}
-
-impl<'t, K, V> Deref<RawTable<K, V>> for &'t mut RawTable<K, V> {
- fn deref(&self) -> &RawTable<K,V> {
- &**self
- }
-}
-
-impl<'t, K, V> DerefMut<RawTable<K, V>> for &'t mut RawTable<K, V> {
- fn deref_mut(&mut self) -> &mut RawTable<K,V> {
- &mut **self
- }
-}
-
-// Buckets hold references to the table.
-impl<K, V, M> FullBucket<K, V, M> {
- /// Borrow a reference to the table.
- pub fn table(&self) -> &M {
- &self.table
- }
- /// Move out the reference to the table.
- pub fn into_table(self) -> M {
- self.table
- }
- /// Get the raw index.
- pub fn index(&self) -> uint {
- self.idx
- }
-}
-
-impl<K, V, M> EmptyBucket<K, V, M> {
- /// Borrow a reference to the table.
- pub fn table(&self) -> &M {
- &self.table
- }
- /// Move out the reference to the table.
- pub fn into_table(self) -> M {
- self.table
- }
-}
-
-impl<K, V, M> Bucket<K, V, M> {
- /// Move out the reference to the table.
- pub fn into_table(self) -> M {
- self.table
- }
- /// Get the raw index.
- pub fn index(&self) -> uint {
- self.idx
- }
-}
-
-impl<K, V, M: Deref<RawTable<K, V>>> Bucket<K, V, M> {
- pub fn new(table: M, hash: &SafeHash) -> Bucket<K, V, M> {
- Bucket::at_index(table, hash.inspect() as uint)
- }
-
- pub fn at_index(table: M, ib_index: uint) -> Bucket<K, V, M> {
- let ib_index = ib_index & (table.capacity() - 1);
- Bucket {
- raw: unsafe {
- table.first_bucket_raw().offset(ib_index as int)
- },
- idx: ib_index,
- table: table
- }
- }
-
- pub fn first(table: M) -> Bucket<K, V, M> {
- Bucket {
- raw: table.first_bucket_raw(),
- idx: 0,
- table: table
- }
- }
-
- /// Reads a bucket at a given index, returning an enum indicating whether
- /// it's initialized or not. You need to match on this enum to get
- /// the appropriate types to call most of the other functions in
- /// this module.
- pub fn peek(self) -> BucketState<K, V, M> {
- match unsafe { *self.raw.hash } {
- EMPTY_BUCKET =>
- Empty(EmptyBucket {
- raw: self.raw,
- idx: self.idx,
- table: self.table
- }),
- _ =>
- Full(FullBucket {
- raw: self.raw,
- idx: self.idx,
- table: self.table
- })
- }
- }
-
- /// Modifies the bucket pointer in place to make it point to the next slot.
- pub fn next(&mut self) {
- // Branchless bucket iteration step.
- // As we reach the end of the table...
- // We take the current idx: 0111111b
- // Xor it by its increment: ^ 1000000b
- // ------------
- // 1111111b
- // Then AND with the capacity: & 1000000b
- // ------------
- // to get the backwards offset: 1000000b
- // ... and it's zero at all other times.
- let maybe_wraparound_dist = (self.idx ^ (self.idx + 1)) & self.table.capacity();
- // Finally, we obtain the offset 1 or the offset -cap + 1.
- let dist = 1i - (maybe_wraparound_dist as int);
-
- self.idx += 1;
-
- unsafe {
- self.raw = self.raw.offset(dist);
- }
- }
-}
-
-impl<K, V, M: Deref<RawTable<K, V>>> EmptyBucket<K, V, M> {
- #[inline]
- pub fn next(self) -> Bucket<K, V, M> {
- let mut bucket = self.into_bucket();
- bucket.next();
- bucket
- }
-
- #[inline]
- pub fn into_bucket(self) -> Bucket<K, V, M> {
- Bucket {
- raw: self.raw,
- idx: self.idx,
- table: self.table
- }
- }
-
- pub fn gap_peek(self) -> Option<GapThenFull<K, V, M>> {
- let gap = EmptyBucket {
- raw: self.raw,
- idx: self.idx,
- table: ()
- };
-
- match self.next().peek() {
- Full(bucket) => {
- Some(GapThenFull {
- gap: gap,
- full: bucket
- })
- }
- Empty(..) => None
- }
- }
-}
-
-impl<K, V, M: DerefMut<RawTable<K, V>>> EmptyBucket<K, V, M> {
- /// Puts given key and value pair, along with the key's hash,
- /// into this bucket in the hashtable. Note how `self` is 'moved' into
- /// this function, because this slot will no longer be empty when
- /// we return! A `FullBucket` is returned for later use, pointing to
- /// the newly-filled slot in the hashtable.
- ///
- /// Use `make_hash` to construct a `SafeHash` to pass to this function.
- pub fn put(mut self, hash: SafeHash, key: K, value: V)
- -> FullBucket<K, V, M> {
- unsafe {
- *self.raw.hash = hash.inspect();
- ptr::write(self.raw.key, key);
- ptr::write(self.raw.val, value);
- }
-
- self.table.size += 1;
-
- FullBucket { raw: self.raw, idx: self.idx, table: self.table }
- }
-}
-
-impl<K, V, M: Deref<RawTable<K, V>>> FullBucket<K, V, M> {
- #[inline]
- pub fn next(self) -> Bucket<K, V, M> {
- let mut bucket = self.into_bucket();
- bucket.next();
- bucket
- }
-
- #[inline]
- pub fn into_bucket(self) -> Bucket<K, V, M> {
- Bucket {
- raw: self.raw,
- idx: self.idx,
- table: self.table
- }
- }
-
- /// Get the distance between this bucket and the 'ideal' location
- /// as determined by the key's hash stored in it.
- ///
- /// In the cited blog posts above, this is called the "distance to
- /// initial bucket", or DIB. Also known as "probe count".
- pub fn distance(&self) -> uint {
- // Calculates the distance one has to travel when going from
- // `hash mod capacity` onwards to `idx mod capacity`, wrapping around
- // if the destination is not reached before the end of the table.
- (self.idx - self.hash().inspect() as uint) & (self.table.capacity() - 1)
- }
-
- #[inline]
- pub fn hash(&self) -> SafeHash {
- unsafe {
- SafeHash {
- hash: *self.raw.hash
- }
- }
- }
-
- /// Gets references to the key and value at a given index.
- pub fn read(&self) -> (&K, &V) {
- unsafe {
- (&*self.raw.key,
- &*self.raw.val)
- }
- }
-}
-
-impl<K, V, M: DerefMut<RawTable<K, V>>> FullBucket<K, V, M> {
- /// Removes this bucket's key and value from the hashtable.
- ///
- /// This works similarly to `put`, building an `EmptyBucket` out of the
- /// taken bucket.
- pub fn take(mut self) -> (EmptyBucket<K, V, M>, K, V) {
- let key = self.raw.key as *const K;
- let val = self.raw.val as *const V;
-
- self.table.size -= 1;
-
- unsafe {
- *self.raw.hash = EMPTY_BUCKET;
- (
- EmptyBucket {
- raw: self.raw,
- idx: self.idx,
- table: self.table
- },
- ptr::read(key),
- ptr::read(val)
- )
- }
- }
-
- pub fn replace(&mut self, h: SafeHash, k: K, v: V) -> (SafeHash, K, V) {
- unsafe {
- let old_hash = ptr::replace(self.raw.hash as *mut SafeHash, h);
- let old_key = ptr::replace(self.raw.key, k);
- let old_val = ptr::replace(self.raw.val, v);
-
- (old_hash, old_key, old_val)
- }
- }
-
- /// Gets mutable references to the key and value at a given index.
- pub fn read_mut(&mut self) -> (&mut K, &mut V) {
- unsafe {
- (&mut *self.raw.key,
- &mut *self.raw.val)
- }
- }
-}
-
-impl<'t, K, V, M: Deref<RawTable<K, V>> + 't> FullBucket<K, V, M> {
- /// Exchange a bucket state for immutable references into the table.
- /// Because the underlying reference to the table is also consumed,
- /// no further changes to the structure of the table are possible;
- /// in exchange for this, the returned references have a longer lifetime
- /// than the references returned by `read()`.
- pub fn into_refs(self) -> (&'t K, &'t V) {
- unsafe {
- (&*self.raw.key,
- &*self.raw.val)
- }
- }
-}
-
-impl<'t, K, V, M: DerefMut<RawTable<K, V>> + 't> FullBucket<K, V, M> {
- /// This works similarly to `into_refs`, exchanging a bucket state
- /// for mutable references into the table.
- pub fn into_mut_refs(self) -> (&'t mut K, &'t mut V) {
- unsafe {
- (&mut *self.raw.key,
- &mut *self.raw.val)
- }
- }
-}
-
-impl<K, V, M> BucketState<K, V, M> {
- // For convenience.
- pub fn expect_full(self) -> FullBucket<K, V, M> {
- match self {
- Full(full) => full,
- Empty(..) => panic!("Expected full bucket")
- }
- }
-}
-
-impl<K, V, M: Deref<RawTable<K, V>>> GapThenFull<K, V, M> {
- #[inline]
- pub fn full(&self) -> &FullBucket<K, V, M> {
- &self.full
- }
-
- pub fn shift(mut self) -> Option<GapThenFull<K, V, M>> {
- unsafe {
- *self.gap.raw.hash = mem::replace(&mut *self.full.raw.hash, EMPTY_BUCKET);
- copy_nonoverlapping_memory(self.gap.raw.key, self.full.raw.key as *const K, 1);
- copy_nonoverlapping_memory(self.gap.raw.val, self.full.raw.val as *const V, 1);
- }
-
- let FullBucket { raw: prev_raw, idx: prev_idx, .. } = self.full;
-
- match self.full.next().peek() {
- Full(bucket) => {
- self.gap.raw = prev_raw;
- self.gap.idx = prev_idx;
-
- self.full = bucket;
-
- Some(self)
- }
- Empty(..) => None
- }
- }
-}
-
-
-/// Rounds up to a multiple of a power of two. Returns the closest multiple
-/// of `target_alignment` that is higher or equal to `unrounded`.
-///
-/// # Failure
-///
-/// Fails if `target_alignment` is not a power of two.
-fn round_up_to_next(unrounded: uint, target_alignment: uint) -> uint {
- assert!(is_power_of_two(target_alignment));
- (unrounded + target_alignment - 1) & !(target_alignment - 1)
-}
-
-#[test]
-fn test_rounding() {
- assert_eq!(round_up_to_next(0, 4), 0);
- assert_eq!(round_up_to_next(1, 4), 4);
- assert_eq!(round_up_to_next(2, 4), 4);
- assert_eq!(round_up_to_next(3, 4), 4);
- assert_eq!(round_up_to_next(4, 4), 4);
- assert_eq!(round_up_to_next(5, 4), 8);
-}
-
-// Returns a tuple of (key_offset, val_offset),
-// from the start of a mallocated array.
-fn calculate_offsets(hashes_size: uint,
- keys_size: uint, keys_align: uint,
- vals_align: uint)
- -> (uint, uint) {
- let keys_offset = round_up_to_next(hashes_size, keys_align);
- let end_of_keys = keys_offset + keys_size;
-
- let vals_offset = round_up_to_next(end_of_keys, vals_align);
-
- (keys_offset, vals_offset)
-}
-
-// Returns a tuple of (minimum required malloc alignment, hash_offset,
-// array_size), from the start of a mallocated array.
-fn calculate_allocation(hash_size: uint, hash_align: uint,
- keys_size: uint, keys_align: uint,
- vals_size: uint, vals_align: uint)
- -> (uint, uint, uint) {
- let hash_offset = 0;
- let (_, vals_offset) = calculate_offsets(hash_size,
- keys_size, keys_align,
- vals_align);
- let end_of_vals = vals_offset + vals_size;
-
- let min_align = cmp::max(hash_align, cmp::max(keys_align, vals_align));
-
- (min_align, hash_offset, end_of_vals)
-}
-
-#[test]
-fn test_offset_calculation() {
- assert_eq!(calculate_allocation(128, 8, 15, 1, 4, 4), (8, 0, 148));
- assert_eq!(calculate_allocation(3, 1, 2, 1, 1, 1), (1, 0, 6));
- assert_eq!(calculate_allocation(6, 2, 12, 4, 24, 8), (8, 0, 48));
- assert_eq!(calculate_offsets(128, 15, 1, 4), (128, 144));
- assert_eq!(calculate_offsets(3, 2, 1, 1), (3, 5));
- assert_eq!(calculate_offsets(6, 12, 4, 8), (8, 24));
-}
-
-impl<K, V> RawTable<K, V> {
- /// Does not initialize the buckets. The caller should ensure they,
- /// at the very least, set every hash to EMPTY_BUCKET.
- unsafe fn new_uninitialized(capacity: uint) -> RawTable<K, V> {
- if capacity == 0 {
- return RawTable {
- size: 0,
- capacity: 0,
- hashes: 0 as *mut u64,
- marker: marker::CovariantType,
- };
- }
- // No need for `checked_mul` before a more restrictive check performed
- // later in this method.
- let hashes_size = capacity * size_of::<u64>();
- let keys_size = capacity * size_of::< K >();
- let vals_size = capacity * size_of::< V >();
-
- // Allocating hashmaps is a little tricky. We need to allocate three
- // arrays, but since we know their sizes and alignments up front,
- // we just allocate a single array, and then have the subarrays
- // point into it.
- //
- // This is great in theory, but in practice getting the alignment
- // right is a little subtle. Therefore, calculating offsets has been
- // factored out into a different function.
- let (malloc_alignment, hash_offset, size) =
- calculate_allocation(
- hashes_size, min_align_of::<u64>(),
- keys_size, min_align_of::< K >(),
- vals_size, min_align_of::< V >());
-
- // One check for overflow that covers calculation and rounding of size.
- let size_of_bucket = size_of::<u64>().checked_add(&size_of::<K>()).unwrap()
- .checked_add(&size_of::<V>()).unwrap();
- assert!(size >= capacity.checked_mul(&size_of_bucket)
- .expect("capacity overflow"),
- "capacity overflow");
-
- let buffer = allocate(size, malloc_alignment);
- if buffer.is_null() { ::alloc::oom() }
-
- let hashes = buffer.offset(hash_offset as int) as *mut u64;
-
- RawTable {
- capacity: capacity,
- size: 0,
- hashes: hashes,
- marker: marker::CovariantType,
- }
- }
-
- fn first_bucket_raw(&self) -> RawBucket<K, V> {
- let hashes_size = self.capacity * size_of::<u64>();
- let keys_size = self.capacity * size_of::<K>();
-
- let buffer = self.hashes as *mut u8;
- let (keys_offset, vals_offset) = calculate_offsets(hashes_size,
- keys_size, min_align_of::<K>(),
- min_align_of::<V>());
-
- unsafe {
- RawBucket {
- hash: self.hashes,
- key: buffer.offset(keys_offset as int) as *mut K,
- val: buffer.offset(vals_offset as int) as *mut V
- }
- }
- }
-
- /// Creates a new raw table from a given capacity. All buckets are
- /// initially empty.
- #[allow(experimental)]
- pub fn new(capacity: uint) -> RawTable<K, V> {
- unsafe {
- let ret = RawTable::new_uninitialized(capacity);
- zero_memory(ret.hashes, capacity);
- ret
- }
- }
-
- /// The hashtable's capacity, similar to a vector's.
- pub fn capacity(&self) -> uint {
- self.capacity
- }
-
- /// The number of elements ever `put` in the hashtable, minus the number
- /// of elements ever `take`n.
- pub fn size(&self) -> uint {
- self.size
- }
-
- fn raw_buckets(&self) -> RawBuckets<K, V> {
- RawBuckets {
- raw: self.first_bucket_raw(),
- hashes_end: unsafe {
- self.hashes.offset(self.capacity as int)
- },
- marker: marker::ContravariantLifetime,
- }
- }
-
- pub fn iter(&self) -> Entries<K, V> {
- Entries {
- iter: self.raw_buckets(),
- elems_left: self.size(),
- }
- }
-
- pub fn iter_mut(&mut self) -> MutEntries<K, V> {
- MutEntries {
- iter: self.raw_buckets(),
- elems_left: self.size(),
- }
- }
-
- pub fn into_iter(self) -> MoveEntries<K, V> {
- let RawBuckets { raw, hashes_end, .. } = self.raw_buckets();
- // Replace the marker regardless of lifetime bounds on parameters.
- MoveEntries {
- iter: RawBuckets {
- raw: raw,
- hashes_end: hashes_end,
- marker: marker::ContravariantLifetime,
- },
- table: self,
- }
- }
-
- /// Returns an iterator that copies out each entry. Used while the table
- /// is being dropped.
- unsafe fn rev_move_buckets(&mut self) -> RevMoveBuckets<K, V> {
- let raw_bucket = self.first_bucket_raw();
- RevMoveBuckets {
- raw: raw_bucket.offset(self.capacity as int),
- hashes_end: raw_bucket.hash,
- elems_left: self.size,
- marker: marker::ContravariantLifetime,
- }
- }
-}
-
-/// A raw iterator. The basis for some other iterators in this module. Although
-/// this interface is safe, it's not used outside this module.
-struct RawBuckets<'a, K, V> {
- raw: RawBucket<K, V>,
- hashes_end: *mut u64,
- marker: marker::ContravariantLifetime<'a>,
-}
-
-impl<'a, K, V> Iterator<RawBucket<K, V>> for RawBuckets<'a, K, V> {
- fn next(&mut self) -> Option<RawBucket<K, V>> {
- while self.raw.hash != self.hashes_end {
- unsafe {
- // We are swapping out the pointer to a bucket and replacing
- // it with the pointer to the next one.
- let prev = ptr::replace(&mut self.raw, self.raw.offset(1));
- if *prev.hash != EMPTY_BUCKET {
- return Some(prev);
- }
- }
- }
-
- None
- }
-}
-
-/// An iterator that moves out buckets in reverse order. It leaves the table
-/// in an an inconsistent state and should only be used for dropping
-/// the table's remaining entries. It's used in the implementation of Drop.
-struct RevMoveBuckets<'a, K, V> {
- raw: RawBucket<K, V>,
- hashes_end: *mut u64,
- elems_left: uint,
- marker: marker::ContravariantLifetime<'a>,
-}
-
-impl<'a, K, V> Iterator<(K, V)> for RevMoveBuckets<'a, K, V> {
- fn next(&mut self) -> Option<(K, V)> {
- if self.elems_left == 0 {
- return None;
- }
-
- loop {
- debug_assert!(self.raw.hash != self.hashes_end);
-
- unsafe {
- self.raw = self.raw.offset(-1);
-
- if *self.raw.hash != EMPTY_BUCKET {
- self.elems_left -= 1;
- return Some((
- ptr::read(self.raw.key as *const K),
- ptr::read(self.raw.val as *const V)
- ));
- }
- }
- }
- }
-}
-
-/// Iterator over shared references to entries in a table.
-pub struct Entries<'a, K: 'a, V: 'a> {
- iter: RawBuckets<'a, K, V>,
- elems_left: uint,
-}
-
-/// Iterator over mutable references to entries in a table.
-pub struct MutEntries<'a, K: 'a, V: 'a> {
- iter: RawBuckets<'a, K, V>,
- elems_left: uint,
-}
-
-/// Iterator over the entries in a table, consuming the table.
-pub struct MoveEntries<K, V> {
- table: RawTable<K, V>,
- iter: RawBuckets<'static, K, V>
-}
-
-impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
- fn next(&mut self) -> Option<(&'a K, &'a V)> {
- self.iter.next().map(|bucket| {
- self.elems_left -= 1;
- unsafe {
- (&*bucket.key,
- &*bucket.val)
- }
- })
- }
-
- fn size_hint(&self) -> (uint, Option<uint>) {
- (self.elems_left, Some(self.elems_left))
- }
-}
-
-impl<'a, K, V> Iterator<(&'a K, &'a mut V)> for MutEntries<'a, K, V> {
- fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
- self.iter.next().map(|bucket| {
- self.elems_left -= 1;
- unsafe {
- (&*bucket.key,
- &mut *bucket.val)
- }
- })
- }
-
- fn size_hint(&self) -> (uint, Option<uint>) {
- (self.elems_left, Some(self.elems_left))
- }
-}
-
-impl<K, V> Iterator<(SafeHash, K, V)> for MoveEntries<K, V> {
- fn next(&mut self) -> Option<(SafeHash, K, V)> {
- self.iter.next().map(|bucket| {
- self.table.size -= 1;
- unsafe {
- (
- SafeHash {
- hash: *bucket.hash,
- },
- ptr::read(bucket.key as *const K),
- ptr::read(bucket.val as *const V)
- )
- }
- })
- }
-
- fn size_hint(&self) -> (uint, Option<uint>) {
- let size = self.table.size();
- (size, Some(size))
- }
-}
-
-impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
- fn clone(&self) -> RawTable<K, V> {
- unsafe {
- let mut new_ht = RawTable::new_uninitialized(self.capacity());
-
- {
- let cap = self.capacity();
- let mut new_buckets = Bucket::first(&mut new_ht);
- let mut buckets = Bucket::first(self);
- while buckets.index() != cap {
- match buckets.peek() {
- Full(full) => {
- let (h, k, v) = {
- let (k, v) = full.read();
- (full.hash(), k.clone(), v.clone())
- };
- *new_buckets.raw.hash = h.inspect();
- ptr::write(new_buckets.raw.key, k);
- ptr::write(new_buckets.raw.val, v);
- }
- Empty(..) => {
- *new_buckets.raw.hash = EMPTY_BUCKET;
- }
- }
- new_buckets.next();
- buckets.next();
- }
- };
-
- new_ht.size = self.size();
-
- new_ht
- }
- }
-}
-
-#[unsafe_destructor]
-impl<K, V> Drop for RawTable<K, V> {
- fn drop(&mut self) {
- if self.hashes.is_null() {
- return;
- }
- // This is done in reverse because we've likely partially taken
- // some elements out with `.into_iter()` from the front.
- // Check if the size is 0, so we don't do a useless scan when
- // dropping empty tables such as on resize.
- // Also avoid double drop of elements that have been already moved out.
- unsafe {
- for _ in self.rev_move_buckets() {}
- }
-
- let hashes_size = self.capacity * size_of::<u64>();
- let keys_size = self.capacity * size_of::<K>();
- let vals_size = self.capacity * size_of::<V>();
- let (align, _, size) = calculate_allocation(hashes_size, min_align_of::<u64>(),
- keys_size, min_align_of::<K>(),
- vals_size, min_align_of::<V>());
-
- unsafe {
- deallocate(self.hashes as *mut u8, size, align);
- // Remember how everything was allocated out of one buffer
- // during initialization? We only need one call to free here.
- }
- }
-}
//! Rust's collections can be grouped into four major categories:
//!
//! * Sequences: `Vec`, `RingBuf`, `DList`, `BitV`
-//! * Maps: `HashMap`, `BTreeMap`, `TreeMap`, `TrieMap`, `SmallIntMap`, `LruCache`
+//! * Maps: `HashMap`, `BTreeMap`, `TreeMap`, `TrieMap`, `VecMap`, `LruCache`
//! * Sets: `HashSet`, `BTreeSet`, `TreeSet`, `TrieSet`, `BitVSet`, `EnumSet`
-//! * Misc: `PriorityQueue`
+//! * Misc: `BinaryHeap`
//!
//! # When Should You Use Which Collection?
//!
//! * You want a `HashMap`, but with many potentially large `uint` keys.
//! * You want a `BTreeMap`, but with potentially large `uint` keys.
//!
-//! ### Use a `SmallIntMap` when:
+//! ### Use a `VecMap` when:
//! * You want a `HashMap` but with known to be small `uint` keys.
//! * You want a `BTreeMap`, but with known to be small `uint` keys.
//!
//! * You want a bitvector.
//!
//! ### Use a `BitVSet` when:
-//! * You want a `SmallIntSet`.
+//! * You want a `VecSet`.
//!
//! ### Use an `EnumSet` when:
//! * You want a C-like enum, stored in a single `uint`.
//!
-//! ### Use a `PriorityQueue` when:
+//! ### Use a `BinaryHeap` when:
//! * You want to store a bunch of elements, but only ever want to process the "biggest"
//! or "most important" one at any given time.
//! * You want a priority queue.
//! #### Counting the number of times each character in a string occurs
//!
//! ```
-//! use std::collections::btree::{BTreeMap, Occupied, Vacant};
+//! use std::collections::btree_map::{BTreeMap, Occupied, Vacant};
//!
//! let mut count = BTreeMap::new();
//! let message = "she sells sea shells by the sea shore";
//! #### Tracking the inebriation of customers at a bar
//!
//! ```
-//! use std::collections::btree::{BTreeMap, Occupied, Vacant};
+//! use std::collections::btree_map::{BTreeMap, Occupied, Vacant};
//!
//! // A client of the bar. They have an id and a blood alcohol level.
//! struct Person { id: u32, blood_alcohol: f32 };
#![experimental]
-pub use core_collections::{Bitv, BitvSet, BTreeMap, BTreeSet, DList, EnumSet};
-pub use core_collections::{PriorityQueue, RingBuf, SmallIntMap};
-pub use core_collections::{TreeMap, TreeSet, TrieMap, TrieSet};
-pub use core_collections::{bitv, btree, dlist, enum_set};
-pub use core_collections::{priority_queue, ringbuf, smallintmap, treemap, trie};
+pub use core_collections::{BinaryHeap, Bitv, BitvSet, BTreeMap, BTreeSet};
+pub use core_collections::{DList, EnumSet, RingBuf};
+pub use core_collections::{TreeMap, TreeSet, TrieMap, TrieSet, VecMap};
-pub use self::hashmap::{HashMap, HashSet};
+pub use core_collections::{binary_heap, bitv, bitv_set, btree_map, btree_set, dlist, enum_set};
+pub use core_collections::{ring_buf, tree_map, tree_set, trie_map, trie_set, vec_map};
+
+pub use self::hash_map::HashMap;
+pub use self::hash_set::HashSet;
pub use self::lru_cache::LruCache;
-pub mod hashmap;
+mod hash;
+
+pub mod hash_map {
+ //! A hashmap
+ pub use super::hash::map::*;
+}
+
+pub mod hash_set {
+ //! A hashset
+ pub use super::hash::set::*;
+}
+
pub mod lru_cache;
use std::cell::RefCell;
use std::rc::Rc;
use std::collections::HashMap;
-use std::collections::hashmap::{Occupied, Vacant};
+use std::collections::hash_map::{Occupied, Vacant};
/// The SCTable contains a table of SyntaxContext_'s. It
/// represents a flattened tree structure, to avoid having
#![allow(missing_docs)]
-use std::collections::hashmap;
-use std::collections::hashmap::{Occupied, Vacant};
+use std::collections::hash_map;
+use std::collections::hash_map::{Occupied, Vacant};
use std::fmt::Show;
use std::hash::Hash;
use std::io;
/// Returns a HashMap with the number of occurrences of every element in the
/// sequence that the iterator exposes.
-pub fn freq_count<T: Iterator<U>, U: Eq+Hash>(mut iter: T) -> hashmap::HashMap<U, uint> {
- let mut map: hashmap::HashMap<U,uint> = hashmap::HashMap::new();
+pub fn freq_count<T: Iterator<U>, U: Eq+Hash>(mut iter: T) -> hash_map::HashMap<U, uint> {
+ let mut map: hash_map::HashMap<U,uint> = hash_map::HashMap::new();
for elem in iter {
match map.entry(elem) {
Occupied(mut entry) => { *entry.get_mut() += 1; },
extern crate rand;
extern crate time;
-use std::collections::bitv::BitvSet;
+use std::collections::BitvSet;
use std::collections::TreeSet;
use std::hash::Hash;
use std::collections::HashSet;
extern crate collections;
extern crate time;
-use std::collections::SmallIntMap;
+use std::collections::VecMap;
use std::os;
use std::uint;
-fn append_sequential(min: uint, max: uint, map: &mut SmallIntMap<uint>) {
+fn append_sequential(min: uint, max: uint, map: &mut VecMap<uint>) {
for i in range(min, max) {
map.insert(i, i + 22u);
}
}
-fn check_sequential(min: uint, max: uint, map: &SmallIntMap<uint>) {
+fn check_sequential(min: uint, max: uint, map: &VecMap<uint>) {
for i in range(min, max) {
assert_eq!(map[i], i + 22u);
}
let mut appendf = 0.0;
for _ in range(0u, rep) {
- let mut map = SmallIntMap::new();
+ let mut map = VecMap::new();
let start = time::precise_time_s();
append_sequential(0u, max, &mut map);
let mid = time::precise_time_s();
// error-pattern:capacity overflow
-use std::collections::hashmap::HashMap;
+use std::collections::hash_map::HashMap;
use std::uint;
use std::mem::size_of;
// These tests used to be separate files, but I wanted to refactor all
// the common code.
-use std::hashmap::{HashMap, HashSet};
+use std::collections::{HashMap, HashSet};
use rbml::reader as EBReader;
use rbml::writer as EBWriter;
#![feature(while_let)]
-use std::collections::PriorityQueue;
+use std::collections::BinaryHeap;
-fn make_pq() -> PriorityQueue<int> {
- PriorityQueue::from_vec(vec![1i,2,3])
+fn make_pq() -> BinaryHeap<int> {
+ BinaryHeap::from_vec(vec![1i,2,3])
}
pub fn main() {