From 112c8a966fbdb52ff2a535dc8e6df3a8b3cb8fb2 Mon Sep 17 00:00:00 2001 From: Alexis Beingessner Date: Thu, 30 Oct 2014 21:25:08 -0400 Subject: refactor libcollections as part of collection reform * 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] --- src/libcollections/binary_heap.rs | 698 +++++++++ src/libcollections/bit.rs | 2764 ++++++++++++++++++++++++++++++++ src/libcollections/bitv.rs | 2761 -------------------------------- src/libcollections/btree/map.rs | 2 +- src/libcollections/btree/mod.rs | 25 +- src/libcollections/btree/set.rs | 2 +- src/libcollections/enum_set.rs | 2 +- src/libcollections/lib.rs | 66 +- src/libcollections/priority_queue.rs | 698 --------- src/libcollections/ring_buf.rs | 1152 ++++++++++++++ src/libcollections/ringbuf.rs | 1152 -------------- src/libcollections/smallintmap.rs | 1052 ------------- src/libcollections/str.rs | 2 +- src/libcollections/tree/map.rs | 1918 +++++++++++++++++++++++ src/libcollections/tree/mod.rs | 36 + src/libcollections/tree/set.rs | 950 +++++++++++ src/libcollections/treemap.rs | 2867 ---------------------------------- src/libcollections/trie.rs | 1899 ---------------------- src/libcollections/trie/map.rs | 1460 +++++++++++++++++ src/libcollections/trie/mod.rs | 20 + src/libcollections/trie/set.rs | 457 ++++++ src/libcollections/vec_map.rs | 1052 +++++++++++++ 22 files changed, 10565 insertions(+), 10470 deletions(-) create mode 100644 src/libcollections/binary_heap.rs create mode 100644 src/libcollections/bit.rs delete mode 100644 src/libcollections/bitv.rs delete mode 100644 src/libcollections/priority_queue.rs create mode 100644 src/libcollections/ring_buf.rs delete mode 100644 src/libcollections/ringbuf.rs delete mode 100644 src/libcollections/smallintmap.rs create mode 100644 src/libcollections/tree/map.rs create mode 100644 src/libcollections/tree/mod.rs create mode 100644 src/libcollections/tree/set.rs delete mode 100644 src/libcollections/treemap.rs delete mode 100644 src/libcollections/trie.rs create mode 100644 src/libcollections/trie/map.rs create mode 100644 src/libcollections/trie/mod.rs create mode 100644 src/libcollections/trie/set.rs create mode 100644 src/libcollections/vec_map.rs (limited to 'src/libcollections') diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs new file mode 100644 index 00000000000..8481111ae91 --- /dev/null +++ b/src/libcollections/binary_heap.rs @@ -0,0 +1,698 @@ +// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! 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 { +//! 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>, 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 { + data: Vec, +} + +impl Default for BinaryHeap { + #[inline] + fn default() -> BinaryHeap { BinaryHeap::new() } +} + +impl BinaryHeap { + /// Creates an empty `BinaryHeap` as a max-heap. + /// + /// # Example + /// + /// ``` + /// use std::collections::BinaryHeap; + /// let pq: BinaryHeap = BinaryHeap::new(); + /// ``` + pub fn new() -> BinaryHeap { 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 = BinaryHeap::with_capacity(10u); + /// ``` + pub fn with_capacity(capacity: uint) -> BinaryHeap { + 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) -> BinaryHeap { + 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 = 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 = 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 = 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 { + 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 { + 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 { 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 { + 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) { self.iter.size_hint() } +} + +impl FromIterator for BinaryHeap { + fn from_iter>(mut iter: Iter) -> BinaryHeap { + let vec: Vec = iter.collect(); + BinaryHeap::from_vec(vec) + } +} + +impl Extendable for BinaryHeap { + fn extend>(&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) { + 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 = BinaryHeap::new(); + assert!(heap.pop().is_none()); + } + + #[test] + fn test_empty_top() { + let empty: BinaryHeap = BinaryHeap::new(); + assert!(empty.top().is_none()); + } + + #[test] + fn test_empty_replace() { + let mut heap: BinaryHeap = 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 = xs.as_slice().iter().rev().map(|&x| x).collect(); + + for &x in xs.iter() { + assert_eq!(q.pop().unwrap(), x); + } + } +} diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs new file mode 100644 index 00000000000..b7085c96aed --- /dev/null +++ b/src/libcollections/bit.rs @@ -0,0 +1,2764 @@ +// 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 or the MIT license +// , 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, Skip>>>>; +// 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, + /// The number of valid bits in the internal representation + nbits: uint +} + +impl Index 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 { + 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` 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 { + 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 for Bitv { + fn from_iter>(iterator: I) -> Bitv { + let mut ret = Bitv::new(); + ret.extend(iterator); + ret + } +} + +impl Extendable for Bitv { + #[inline] + fn extend>(&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 { + 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 hash::Hash 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 for Bits<'a> { + #[inline] + fn next(&mut self) -> Option { + 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) { + let rem = self.end_idx - self.next_idx; + (rem, Some(rem)) + } +} + +impl<'a> DoubleEndedIterator for Bits<'a> { + #[inline] + fn next_back(&mut self) -> Option { + if self.next_idx != self.end_idx { + self.end_idx -= 1; + Some(self.bitv.get(self.end_idx)) + } else { + None + } + } +} + +impl<'a> ExactSize for Bits<'a> {} + +impl<'a> RandomAccessIterator for Bits<'a> { + #[inline] + fn indexable(&self) -> uint { + self.end_idx - self.next_idx + } + + #[inline] + fn idx(&mut self, index: uint) -> Option { + 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 for BitvSet { + fn from_iter>(iterator: I) -> BitvSet { + let mut ret = BitvSet::new(); + ret.extend(iterator); + ret + } +} + +impl Extendable for BitvSet { + #[inline] + fn extend>(&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 { + 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> { + 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 hash::Hash 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 for BitPositions<'a> { + fn next(&mut self) -> Option { + 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) { + (0, Some(self.set.capacity() - self.next_idx)) + } +} + +impl<'a> Iterator for TwoBitPositions<'a> { + fn next(&mut self) -> Option { + 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) { + 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::>(), 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::>(), 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::>(), 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 = 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::>(); + + let idxs: Vec = 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::>(); + 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::>(); + 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::>(); + 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::>(); + 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 + }) + } +} diff --git a/src/libcollections/bitv.rs b/src/libcollections/bitv.rs deleted file mode 100644 index 26e0c73724c..00000000000 --- a/src/libcollections/bitv.rs +++ /dev/null @@ -1,2761 +0,0 @@ -// 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 or the MIT license -// , 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, Skip>>>>; -// 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, - /// The number of valid bits in the internal representation - nbits: uint -} - -impl Index 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 { - 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` 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 { - 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 for Bitv { - fn from_iter>(iterator: I) -> Bitv { - let mut ret = Bitv::new(); - ret.extend(iterator); - ret - } -} - -impl Extendable for Bitv { - #[inline] - fn extend>(&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 { - 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 hash::Hash 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 for Bits<'a> { - #[inline] - fn next(&mut self) -> Option { - 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) { - let rem = self.end_idx - self.next_idx; - (rem, Some(rem)) - } -} - -impl<'a> DoubleEndedIterator for Bits<'a> { - #[inline] - fn next_back(&mut self) -> Option { - if self.next_idx != self.end_idx { - self.end_idx -= 1; - Some(self.bitv.get(self.end_idx)) - } else { - None - } - } -} - -impl<'a> ExactSize for Bits<'a> {} - -impl<'a> RandomAccessIterator for Bits<'a> { - #[inline] - fn indexable(&self) -> uint { - self.end_idx - self.next_idx - } - - #[inline] - fn idx(&mut self, index: uint) -> Option { - 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 for BitvSet { - fn from_iter>(iterator: I) -> BitvSet { - let mut ret = BitvSet::new(); - ret.extend(iterator); - ret - } -} - -impl Extendable for BitvSet { - #[inline] - fn extend>(&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 { - 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> { - 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 hash::Hash 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 for BitPositions<'a> { - fn next(&mut self) -> Option { - 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) { - (0, Some(self.set.capacity() - self.next_idx)) - } -} - -impl<'a> Iterator for TwoBitPositions<'a> { - fn next(&mut self) -> Option { - 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) { - 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::>(), 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::>(), 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::>(), 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 = 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::>(); - - let idxs: Vec = 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::>(); - 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::>(); - 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::>(); - 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::>(); - 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 - }) - } -} diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 4570d49ba0a..e3dfabfa295 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -23,7 +23,7 @@ use core::default::Default; use core::{iter, fmt, mem}; use core::fmt::Show; -use ringbuf::RingBuf; +use ring_buf::RingBuf; /// A map based on a B-Tree. /// diff --git a/src/libcollections/btree/mod.rs b/src/libcollections/btree/mod.rs index 653de91c0ff..282128099da 100644 --- a/src/libcollections/btree/mod.rs +++ b/src/libcollections/btree/mod.rs @@ -8,27 +8,6 @@ // 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; diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index eac74098758..27752207b97 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -13,7 +13,7 @@ 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}; diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index b78c1897b06..bcae4fe68c9 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -155,7 +155,7 @@ mod test { use std::prelude::*; use std::mem; - use enum_set::{EnumSet, CLike}; + use super::{EnumSet, CLike}; #[deriving(PartialEq, Show)] #[repr(uint)] diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index e28bc766480..5ec8a85fb0f 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -37,34 +37,72 @@ extern crate alloc; #[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; diff --git a/src/libcollections/priority_queue.rs b/src/libcollections/priority_queue.rs deleted file mode 100644 index 885b5c99c45..00000000000 --- a/src/libcollections/priority_queue.rs +++ /dev/null @@ -1,698 +0,0 @@ -// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! 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 { -//! 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>, 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 { - data: Vec, -} - -impl Default for PriorityQueue { - #[inline] - fn default() -> PriorityQueue { PriorityQueue::new() } -} - -impl PriorityQueue { - /// Creates an empty `PriorityQueue` as a max-heap. - /// - /// # Example - /// - /// ``` - /// use std::collections::PriorityQueue; - /// let pq: PriorityQueue = PriorityQueue::new(); - /// ``` - pub fn new() -> PriorityQueue { 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 = PriorityQueue::with_capacity(10u); - /// ``` - pub fn with_capacity(capacity: uint) -> PriorityQueue { - 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) -> PriorityQueue { - 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 = 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 = 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 = 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 { - 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 { - 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 { 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 { - 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) { self.iter.size_hint() } -} - -impl FromIterator for PriorityQueue { - fn from_iter>(mut iter: Iter) -> PriorityQueue { - let vec: Vec = iter.collect(); - PriorityQueue::from_vec(vec) - } -} - -impl Extendable for PriorityQueue { - fn extend>(&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) { - 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 = PriorityQueue::new(); - assert!(heap.pop().is_none()); - } - - #[test] - fn test_empty_top() { - let empty: PriorityQueue = PriorityQueue::new(); - assert!(empty.top().is_none()); - } - - #[test] - fn test_empty_replace() { - let mut heap: PriorityQueue = 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 = xs.as_slice().iter().rev().map(|&x| x).collect(); - - for &x in xs.iter() { - assert_eq!(q.pop().unwrap(), x); - } - } -} diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/ring_buf.rs new file mode 100644 index 00000000000..3c4c3fce61d --- /dev/null +++ b/src/libcollections/ring_buf.rs @@ -0,0 +1,1152 @@ +// 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 or the MIT license +// , 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 { + nelts: uint, + lo: uint, + elts: Vec> +} + +impl Default for RingBuf { + #[inline] + fn default() -> RingBuf { RingBuf::new() } +} + +impl RingBuf { + /// Creates an empty `RingBuf`. + pub fn new() -> RingBuf { + RingBuf::with_capacity(INITIAL_CAPACITY) + } + + /// Creates an empty `RingBuf` with space for at least `n` elements. + pub fn with_capacity(n: uint) -> RingBuf { + 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::>().as_slice(), b); + /// ``` + pub fn iter(&self) -> Items { + 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::>()[], b); + /// ``` + pub fn iter_mut(&mut self) -> MutItems { + 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 { + 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 { + 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], +} + +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) { + 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>, + remaining2: slice::MutItems<'a, Option>, + 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) { + (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(nelts: uint, loptr: &mut uint, elts: &mut Vec>) { + 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 PartialEq for RingBuf { + fn eq(&self, other: &RingBuf) -> bool { + self.nelts == other.nelts && + self.iter().zip(other.iter()).all(|(a, b)| a.eq(b)) + } + fn ne(&self, other: &RingBuf) -> bool { + !self.eq(other) + } +} + +impl Eq for RingBuf {} + +impl PartialOrd for RingBuf { + fn partial_cmp(&self, other: &RingBuf) -> Option { + iter::order::partial_cmp(self.iter(), other.iter()) + } +} + +impl Ord for RingBuf { + #[inline] + fn cmp(&self, other: &RingBuf) -> Ordering { + iter::order::cmp(self.iter(), other.iter()) + } +} + +impl> Hash for RingBuf { + fn hash(&self, state: &mut S) { + self.len().hash(state); + for elt in self.iter() { + elt.hash(state); + } + } +} + +impl Index for RingBuf { + #[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 IndexMut for RingBuf { + #[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 FromIterator for RingBuf { + fn from_iter>(iterator: T) -> RingBuf { + let (lower, _) = iterator.size_hint(); + let mut deq = RingBuf::with_capacity(lower); + deq.extend(iterator); + deq + } +} + +impl Extendable for RingBuf { + fn extend>(&mut self, mut iterator: T) { + for elt in iterator { + self.push(elt); + } + } +} + +impl fmt::Show for RingBuf { + 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(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 = 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 { + 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::(5, 72, 64, 175); + } + + #[test] + fn test_param_taggy() { + test_parameterized::(One(1), Two(1, 2), Three(1, 2, 3), Two(17, 42)); + } + + #[test] + fn test_param_taggypar() { + test_parameterized::>(Onepar::(1), + Twopar::(1, 2), + Threepar::(1, 2, 3), + Twopar::(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::(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 = range(0i, 5).collect(); + d.pop_front(); + d.swap(0, 3); + assert_eq!(d.iter().map(|&x|x).collect::>(), 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::>().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::>().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::>().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::>().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!(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 = v.iter().map(|&x| x).collect(); + let u: Vec = deq.iter().map(|&x| x).collect(); + assert_eq!(u, v); + + let mut seq = iter::count(0u, 2).take(256); + let deq: RingBuf = 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 = 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]"); + } +} diff --git a/src/libcollections/ringbuf.rs b/src/libcollections/ringbuf.rs deleted file mode 100644 index 3c4c3fce61d..00000000000 --- a/src/libcollections/ringbuf.rs +++ /dev/null @@ -1,1152 +0,0 @@ -// 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 or the MIT license -// , 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 { - nelts: uint, - lo: uint, - elts: Vec> -} - -impl Default for RingBuf { - #[inline] - fn default() -> RingBuf { RingBuf::new() } -} - -impl RingBuf { - /// Creates an empty `RingBuf`. - pub fn new() -> RingBuf { - RingBuf::with_capacity(INITIAL_CAPACITY) - } - - /// Creates an empty `RingBuf` with space for at least `n` elements. - pub fn with_capacity(n: uint) -> RingBuf { - 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::>().as_slice(), b); - /// ``` - pub fn iter(&self) -> Items { - 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::>()[], b); - /// ``` - pub fn iter_mut(&mut self) -> MutItems { - 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 { - 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 { - 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], -} - -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) { - 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>, - remaining2: slice::MutItems<'a, Option>, - 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) { - (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(nelts: uint, loptr: &mut uint, elts: &mut Vec>) { - 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 PartialEq for RingBuf { - fn eq(&self, other: &RingBuf) -> bool { - self.nelts == other.nelts && - self.iter().zip(other.iter()).all(|(a, b)| a.eq(b)) - } - fn ne(&self, other: &RingBuf) -> bool { - !self.eq(other) - } -} - -impl Eq for RingBuf {} - -impl PartialOrd for RingBuf { - fn partial_cmp(&self, other: &RingBuf) -> Option { - iter::order::partial_cmp(self.iter(), other.iter()) - } -} - -impl Ord for RingBuf { - #[inline] - fn cmp(&self, other: &RingBuf) -> Ordering { - iter::order::cmp(self.iter(), other.iter()) - } -} - -impl> Hash for RingBuf { - fn hash(&self, state: &mut S) { - self.len().hash(state); - for elt in self.iter() { - elt.hash(state); - } - } -} - -impl Index for RingBuf { - #[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 IndexMut for RingBuf { - #[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 FromIterator for RingBuf { - fn from_iter>(iterator: T) -> RingBuf { - let (lower, _) = iterator.size_hint(); - let mut deq = RingBuf::with_capacity(lower); - deq.extend(iterator); - deq - } -} - -impl Extendable for RingBuf { - fn extend>(&mut self, mut iterator: T) { - for elt in iterator { - self.push(elt); - } - } -} - -impl fmt::Show for RingBuf { - 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(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 = 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 { - 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::(5, 72, 64, 175); - } - - #[test] - fn test_param_taggy() { - test_parameterized::(One(1), Two(1, 2), Three(1, 2, 3), Two(17, 42)); - } - - #[test] - fn test_param_taggypar() { - test_parameterized::>(Onepar::(1), - Twopar::(1, 2), - Threepar::(1, 2, 3), - Twopar::(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::(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 = range(0i, 5).collect(); - d.pop_front(); - d.swap(0, 3); - assert_eq!(d.iter().map(|&x|x).collect::>(), 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::>().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::>().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::>().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::>().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!(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 = v.iter().map(|&x| x).collect(); - let u: Vec = deq.iter().map(|&x| x).collect(); - assert_eq!(u, v); - - let mut seq = iter::count(0u, 2).take(256); - let deq: RingBuf = 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 = 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]"); - } -} diff --git a/src/libcollections/smallintmap.rs b/src/libcollections/smallintmap.rs deleted file mode 100644 index b2e018743da..00000000000 --- a/src/libcollections/smallintmap.rs +++ /dev/null @@ -1,1052 +0,0 @@ -// 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 or the MIT license -// , 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 { - v: Vec>, -} - -impl Default for SmallIntMap { - #[inline] - fn default() -> SmallIntMap { SmallIntMap::new() } -} - -impl Clone for SmallIntMap { - #[inline] - fn clone(&self) -> SmallIntMap { - SmallIntMap { v: self.v.clone() } - } - - #[inline] - fn clone_from(&mut self, source: &SmallIntMap) { - self.v.reserve(source.v.len()); - for (i, w) in self.v.iter_mut().enumerate() { - *w = source.v[i].clone(); - } - } -} - -impl > Hash for SmallIntMap { - fn hash(&self, state: &mut S) { - self.v.hash(state) - } -} - -impl SmallIntMap { - /// Creates an empty `SmallIntMap`. - /// - /// # Example - /// - /// ``` - /// use std::collections::SmallIntMap; - /// let mut map: SmallIntMap<&str> = SmallIntMap::new(); - /// ``` - pub fn new() -> SmallIntMap { 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 { - 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), (uint, V), - Enumerate>>> - { - 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 { - 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 { - if *key >= self.v.len() { - return None; - } - self.v[*key].take() - } -} - -impl SmallIntMap { - /// 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 PartialOrd for SmallIntMap { - #[inline] - fn partial_cmp(&self, other: &SmallIntMap) -> Option { - iter::order::partial_cmp(self.iter(), other.iter()) - } -} - -impl Ord for SmallIntMap { - #[inline] - fn cmp(&self, other: &SmallIntMap) -> Ordering { - iter::order::cmp(self.iter(), other.iter()) - } -} - -impl fmt::Show for SmallIntMap { - 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 FromIterator<(uint, V)> for SmallIntMap { - fn from_iter>(iter: Iter) -> SmallIntMap { - let mut map = SmallIntMap::new(); - map.extend(iter); - map - } -} - -impl Extendable<(uint, V)> for SmallIntMap { - fn extend>(&mut self, mut iter: Iter) { - for (k, v) in iter { - self.insert(k, v); - } - } -} - -impl Index for SmallIntMap { - #[inline] - fn index<'a>(&'a self, i: &uint) -> &'a V { - self.find(i).expect("key not present") - } -} - -impl IndexMut for SmallIntMap { - #[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) { - (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> -} - -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> -} - -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::>(); - 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::>(); - 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::::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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = SmallIntMap::new(); - find_seq_n(10_000, &mut m, b, - |m, i| { m.insert(i, 1); }, - |m, i| { m.find(&i); }); - } -} diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 297ba71d252..2d6cf865878 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -65,7 +65,7 @@ use core::prelude::{PartialEq, PartialOrd, Result, AsSlice, Some, Tuple2}; use core::prelude::{range}; use hash; -use ringbuf::RingBuf; +use ring_buf::RingBuf; use string::String; use unicode; use vec::Vec; diff --git a/src/libcollections/tree/map.rs b/src/libcollections/tree/map.rs new file mode 100644 index 00000000000..9742bddb1f6 --- /dev/null +++ b/src/libcollections/tree/map.rs @@ -0,0 +1,1918 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use core::prelude::*; + +use alloc::boxed::Box; +use core::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 { +/// Some(self.cmp(other)) +/// } +/// } +/// +/// // Use a map to store trolls, sorted by level, and track a list of +/// // heroes slain. +/// let mut trolls = TreeMap::new(); +/// +/// trolls.insert(Troll { name: "Orgarr", level: 2 }, +/// vec!["King Karl"]); +/// trolls.insert(Troll { name: "Blargarr", level: 3 }, +/// vec!["Odd"]); +/// trolls.insert(Troll { name: "Kron the Smelly One", level: 4 }, +/// vec!["Omar the Brave", "Peter: Slayer of Trolls"]); +/// trolls.insert(Troll { name: "Wartilda", level: 1 }, +/// vec![]); +/// +/// println!("You are facing {} trolls!", trolls.len()); +/// +/// // Print the trolls, ordered by level with smallest level first +/// for (troll, heroes) in trolls.iter() { +/// let what = if heroes.len() == 1u { "hero" } +/// else { "heroes" }; +/// +/// println!("level {}: '{}' has slain {} {}", +/// troll.level, troll.name, heroes.len(), what); +/// } +/// +/// // Kill all trolls +/// trolls.clear(); +/// assert_eq!(trolls.len(), 0); +/// ``` + +// Future improvements: + +// range search - O(log n) retrieval of an iterator from some key + +// (possibly) implement the overloads Python does for sets: +// * intersection: & +// * difference: - +// * symmetric difference: ^ +// * union: | +// These would be convenient since the methods work like `each` + +#[deriving(Clone)] +pub struct TreeMap { + root: Option>>, + length: uint +} + +impl PartialEq for TreeMap { + fn eq(&self, other: &TreeMap) -> bool { + self.len() == other.len() && + self.iter().zip(other.iter()).all(|(a, b)| a == b) + } +} + +impl Eq for TreeMap {} + +impl PartialOrd for TreeMap { + #[inline] + fn partial_cmp(&self, other: &TreeMap) -> Option { + iter::order::partial_cmp(self.iter(), other.iter()) + } +} + +impl Ord for TreeMap { + #[inline] + fn cmp(&self, other: &TreeMap) -> Ordering { + iter::order::cmp(self.iter(), other.iter()) + } +} + +impl Show for TreeMap { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + try!(write!(f, "{{")); + + for (i, (k, v)) in self.iter().enumerate() { + if i != 0 { try!(write!(f, ", ")); } + try!(write!(f, "{}: {}", *k, *v)); + } + + write!(f, "}}") + } +} + +impl Default for TreeMap { + #[inline] + fn default() -> TreeMap { TreeMap::new() } +} + +impl Index for TreeMap { + #[inline] + fn index<'a>(&'a self, i: &K) -> &'a V { + self.find(i).expect("no entry found for key") + } +} + +impl IndexMut for TreeMap { + #[inline] + fn index_mut<'a>(&'a mut self, i: &K) -> &'a mut V { + self.find_mut(i).expect("no entry found for key") + } +} + +impl TreeMap { + /// Creates an empty `TreeMap`. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// let mut map: TreeMap<&str, int> = TreeMap::new(); + /// ``` + pub fn new() -> TreeMap { 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 { + 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 { + 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 { + let ret = remove(&mut self.root, key); + if ret.is_some() { self.length -= 1 } + ret + } +} + +impl TreeMap { + /// Returns the value for which `f(key)` returns `Equal`. `f` is invoked + /// with current key and guides tree navigation. That means `f` should + /// be aware of natural ordering of the tree. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// + /// fn get_headers() -> TreeMap { + /// let mut result = TreeMap::new(); + /// result.insert("Content-Type".to_string(), "application/xml".to_string()); + /// result.insert("User-Agent".to_string(), "Curl-Rust/0.1".to_string()); + /// result + /// } + /// + /// let headers = get_headers(); + /// let ua_key = "User-Agent"; + /// let ua = headers.find_with(|k| { + /// ua_key.cmp(&k.as_slice()) + /// }); + /// + /// assert_eq!((*ua.unwrap()).as_slice(), "Curl-Rust/0.1"); + /// ``` + #[inline] + 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 TreeMap { + /// Gets a lazy iterator that should be initialized using + /// `traverse_left`/`traverse_right`/`traverse_complete`. + fn iter_for_traversal<'a>(&'a self) -> Entries<'a, K, V> { + Entries { + stack: vec!(), + node: deref(&self.root), + remaining_min: 0, + remaining_max: self.length + } + } + + /// Returns a lazy iterator to the first key-value pair whose key is not less than `k` + /// If all keys in map are less than `k` an empty iterator is returned. + /// + /// # 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>, + // See the comment on MutEntries; this is just to allow + // code-sharing (for this immutable-values iterator it *could* very + // well be Option<&'a TreeNode>). + node: *const TreeNode, + remaining_min: uint, + remaining_max: uint +} + +/// Lazy backward iterator over a map +pub struct RevEntries<'a, K:'a, V:'a> { + iter: Entries<'a, K, V>, +} + +/// Lazy forward iterator over a map that allows for the mutation of +/// the values. +pub struct MutEntries<'a, K:'a, V:'a> { + stack: Vec<&'a mut TreeNode>, + // Unfortunately, we require some unsafe-ness to get around the + // fact that we would be storing a reference *into* one of the + // nodes in the stack. + // + // As far as the compiler knows, this would let us invalidate the + // reference by assigning a new value to this node's position in + // its parent, which would cause this current one to be + // deallocated so this reference would be invalid. (i.e. the + // compilers complaints are 100% correct.) + // + // However, as far as you humans reading this code know (or are + // about to know, if you haven't read far enough down yet), we are + // only reading from the TreeNode.{left,right} fields. the only + // thing that is ever mutated is the .value field (although any + // actual mutation that happens is done externally, by the + // iterator consumer). So, don't be so concerned, rustc, we've got + // it under control. + // + // (This field can legitimately be null.) + node: *mut TreeNode, + remaining_min: uint, + remaining_max: uint +} + +/// Lazy backward iterator over a map +pub struct RevMutEntries<'a, K:'a, V:'a> { + iter: MutEntries<'a, K, V>, +} + +/// TreeMap keys iterator. +pub type Keys<'a, K, V> = + iter::Map<'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 `& ` token +// sequence and forces their evaluation as an expression. +macro_rules! addr { ($e:expr) => { $e }} +// putting an optional mut into type signatures +macro_rules! item { ($i:item) => { $i }} + +macro_rules! define_iterator { + ($name:ident, + $rev_name:ident, + + // the function to go from &m Option> to *m TreeNode + deref = $deref:ident, + + // see comment on `addr!`, this is just an optional `mut`, but + // there's no support for 0-or-1 repeats. + addr_mut = $($addr_mut:tt)* + ) => { + // private methods on the forward iterator (item!() for the + // addr_mut in the next_ return value) + item!(impl<'a, K, V> $name<'a, K, V> { + #[inline(always)] + fn next_(&mut self, forward: bool) -> Option<(&'a K, &'a $($addr_mut)* V)> { + while !self.stack.is_empty() || !self.node.is_null() { + if !self.node.is_null() { + let node = unsafe {addr!(& $($addr_mut)* *self.node)}; + { + let next_node = if forward { + addr!(& $($addr_mut)* node.left) + } else { + addr!(& $($addr_mut)* node.right) + }; + self.node = $deref(next_node); + } + self.stack.push(node); + } else { + let node = self.stack.pop().unwrap(); + let next_node = if forward { + addr!(& $($addr_mut)* node.right) + } else { + addr!(& $($addr_mut)* node.left) + }; + self.node = $deref(next_node); + self.remaining_max -= 1; + if self.remaining_min > 0 { + self.remaining_min -= 1; + } + return Some((&node.key, addr!(& $($addr_mut)* node.value))); + } + } + None + } + + /// traverse_left, traverse_right and traverse_complete are + /// used to initialize Entries/MutEntries + /// pointing to element inside tree structure. + /// + /// They should be used in following manner: + /// - create iterator using TreeMap::[mut_]iter_for_traversal + /// - find required node using `traverse_left`/`traverse_right` + /// (current node is `Entries::node` field) + /// - complete initialization with `traverse_complete` + /// + /// After this, iteration will start from `self.node`. If + /// `self.node` is None iteration will start from last + /// node from which we traversed left. + #[inline] + fn traverse_left(&mut self) { + let node = unsafe {addr!(& $($addr_mut)* *self.node)}; + self.node = $deref(addr!(& $($addr_mut)* node.left)); + self.stack.push(node); + } + + #[inline] + fn traverse_right(&mut self) { + let node = unsafe {addr!(& $($addr_mut)* *self.node)}; + self.node = $deref(addr!(& $($addr_mut)* node.right)); + } + + #[inline] + fn traverse_complete(&mut self) { + if !self.node.is_null() { + unsafe { + self.stack.push(addr!(& $($addr_mut)* *self.node)); + } + self.node = ptr::RawPtr::null(); + } + } + }) + + // the forward Iterator impl. + item!(impl<'a, K, V> Iterator<(&'a K, &'a $($addr_mut)* V)> for $name<'a, K, V> { + /// Advances the iterator to the next node (in order) and return a + /// tuple with a reference to the key and value. If there are no + /// more nodes, return `None`. + fn next(&mut self) -> Option<(&'a K, &'a $($addr_mut)* V)> { + self.next_(true) + } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + (self.remaining_min, Some(self.remaining_max)) + } + }) + + // the reverse Iterator impl. + item!(impl<'a, K, V> Iterator<(&'a K, &'a $($addr_mut)* V)> for $rev_name<'a, K, V> { + fn next(&mut self) -> Option<(&'a K, &'a $($addr_mut)* V)> { + self.iter.next_(false) + } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + self.iter.size_hint() + } + }) + } +} // end of define_iterator + +define_iterator! { + Entries, + RevEntries, + deref = deref, + + // immutable, so no mut + addr_mut = +} +define_iterator! { + MutEntries, + RevMutEntries, + deref = deref_mut, + + addr_mut = mut +} + +fn deref<'a, K, V>(node: &'a Option>>) -> *const TreeNode { + match *node { + Some(ref n) => { + let n: &TreeNode = &**n; + n as *const TreeNode + } + None => ptr::null() + } +} + +fn deref_mut(x: &mut Option>>) + -> *mut TreeNode { + match *x { + Some(ref mut n) => { + let n: &mut TreeNode = &mut **n; + n as *mut TreeNode + } + None => ptr::null_mut() + } +} + +/// Lazy forward iterator over a map that consumes the map while iterating +pub struct MoveEntries { + stack: Vec>, + remaining: uint +} + +impl Iterator<(K, V)> for MoveEntries { + #[inline] + fn next(&mut self) -> Option<(K, V)> { + while !self.stack.is_empty() { + let TreeNode { + key, + value, + left, + right, + level, + } = self.stack.pop().unwrap(); + + match left { + Some(box left) => { + let n = TreeNode { + key: key, + value: value, + left: None, + right: right, + level: level + }; + self.stack.push(n); + self.stack.push(left); + } + None => { + match right { + Some(box right) => self.stack.push(right), + None => () + } + self.remaining -= 1; + return Some((key, value)) + } + } + } + None + } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + (self.remaining, Some(self.remaining)) + } + +} + + + +// Nodes keep track of their level in the tree, starting at 1 in the +// leaves and with a red child sharing the level of the parent. +#[deriving(Clone)] +struct TreeNode { + key: K, + value: V, + left: Option>>, + right: Option>>, + level: uint +} + +impl TreeNode { + /// Creates a new tree node. + #[inline] + pub fn new(key: K, value: V) -> TreeNode { + TreeNode{key: key, value: value, left: None, right: None, level: 1} + } +} + +// Remove left horizontal link by rotating right +fn skew(node: &mut Box>) { + if node.left.as_ref().map_or(false, |x| x.level == node.level) { + let mut save = node.left.take().unwrap(); + swap(&mut node.left, &mut save.right); // save.right now None + swap(node, &mut save); + node.right = Some(save); + } +} + +// Remove dual horizontal link by rotating left and increasing level of +// the parent +fn split(node: &mut Box>) { + if node.right.as_ref().map_or(false, + |x| x.right.as_ref().map_or(false, |y| y.level == node.level)) { + let mut save = node.right.take().unwrap(); + swap(&mut node.right, &mut save.left); // save.left now None + save.level += 1; + swap(node, &mut save); + node.left = Some(save); + } +} + +// Next 2 functions have the same convention: comparator gets +// at input current key and returns search_key cmp cur_key +// (i.e. search_key.cmp(&cur_key)) +fn tree_find_with<'r, K, V>(node: &'r Option>>, + f: |&K| -> Ordering) -> Option<&'r V> { + let mut current: &'r Option>> = node; + loop { + match *current { + Some(ref r) => { + match f(&r.key) { + Less => current = &r.left, + Greater => current = &r.right, + Equal => return Some(&r.value) + } + } + None => return None + } + } +} + +// See comments above tree_find_with +fn tree_find_with_mut<'r, K, V>(node: &'r mut Option>>, + 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(node: &mut Option>>, + key: K, value: V) -> Option { + match *node { + Some(ref mut save) => { + match key.cmp(&save.key) { + Less => { + let inserted = insert(&mut save.left, key, value); + skew(save); + split(save); + inserted + } + Greater => { + let inserted = insert(&mut save.right, key, value); + skew(save); + split(save); + inserted + } + Equal => { + save.key = key; + Some(replace(&mut save.value, value)) + } + } + } + None => { + *node = Some(box TreeNode::new(key, value)); + None + } + } +} + +fn remove(node: &mut Option>>, + key: &K) -> Option { + fn heir_swap(node: &mut Box>, + child: &mut Option>>) { + // *could* be done without recursion, but it won't borrow check + for x in child.iter_mut() { + if x.right.is_some() { + heir_swap(node, &mut x.right); + } else { + swap(&mut node.key, &mut x.key); + swap(&mut node.value, &mut x.value); + } + } + } + + match *node { + None => { + return None; // bottom of tree + } + Some(ref mut save) => { + let (ret, rebalance) = match key.cmp(&save.key) { + Less => (remove(&mut save.left, key), true), + Greater => (remove(&mut save.right, key), true), + Equal => { + if save.left.is_some() { + if save.right.is_some() { + let mut left = save.left.take().unwrap(); + if left.right.is_some() { + heir_swap(save, &mut left.right); + } else { + swap(&mut save.key, &mut left.key); + swap(&mut save.value, &mut left.value); + } + save.left = Some(left); + (remove(&mut save.left, key), true) + } else { + let new = save.left.take().unwrap(); + let box TreeNode{value, ..} = replace(save, new); + *save = save.left.take().unwrap(); + (Some(value), true) + } + } else if save.right.is_some() { + let new = save.right.take().unwrap(); + let box TreeNode{value, ..} = replace(save, new); + (Some(value), true) + } else { + (None, false) + } + } + }; + + if rebalance { + let left_level = save.left.as_ref().map_or(0, |x| x.level); + let right_level = save.right.as_ref().map_or(0, |x| x.level); + + // re-balance, if necessary + if left_level < save.level - 1 || right_level < save.level - 1 { + save.level -= 1; + + if right_level > save.level { + let save_level = save.level; + for x in save.right.iter_mut() { x.level = save_level } + } + + skew(save); + + for right in save.right.iter_mut() { + skew(right); + for x in right.right.iter_mut() { skew(x) } + } + + split(save); + for x in save.right.iter_mut() { split(x) } + } + + return ret; + } + } + } + return match node.take() { + Some(box TreeNode{value, ..}) => Some(value), None => panic!() + }; +} + +impl FromIterator<(K, V)> for TreeMap { + fn from_iter>(iter: T) -> TreeMap { + let mut map = TreeMap::new(); + map.extend(iter); + map + } +} + +impl Extendable<(K, V)> for TreeMap { + #[inline] + fn extend>(&mut self, mut iter: T) { + for (k, v) in iter { + self.insert(k, v); + } + } +} + +impl, V: Hash> Hash for TreeMap { + fn hash(&self, state: &mut S) { + for elt in self.iter() { + elt.hash(state); + } + } +} + + +#[cfg(test)] +mod test_treemap { + use std::prelude::*; + use std::rand::Rng; + use std::rand; + + use super::{TreeMap, TreeNode}; + + #[test] + fn find_empty() { + let m: TreeMap = TreeMap::new(); + assert!(m.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(ctrl: &[(K, V)], + map: &TreeMap) { + assert_eq!(ctrl.is_empty(), map.is_empty()); + for x in ctrl.iter() { + let &(ref k, ref v) = x; + assert!(map.find(k).unwrap() == v) + } + for (map_k, map_v) in map.iter() { + let mut found = false; + for x in ctrl.iter() { + let &(ref ctrl_k, ref ctrl_v) = x; + if *map_k == *ctrl_k { + assert!(*map_v == *ctrl_v); + found = true; + break; + } + } + assert!(found); + } + } + + fn check_left(node: &Option>>, + parent: &Box>) { + match *node { + Some(ref r) => { + assert_eq!(r.key.cmp(&parent.key), Less); + assert!(r.level == parent.level - 1); // left is black + check_left(&r.left, r); + check_right(&r.right, r, false); + } + None => assert!(parent.level == 1) // parent is leaf + } + } + + fn check_right(node: &Option>>, + parent: &Box>, + parent_red: bool) { + match *node { + Some(ref r) => { + assert_eq!(r.key.cmp(&parent.key), Greater); + let red = r.level == parent.level; + if parent_red { assert!(!red) } // no dual horizontal links + // Right red or black + assert!(red || r.level == parent.level - 1); + check_left(&r.left, r); + check_right(&r.right, r, red); + } + None => assert!(parent.level == 1) // parent is leaf + } + } + + fn check_structure(map: &TreeMap) { + match map.root { + Some(ref r) => { + check_left(&r.left, r); + check_right(&r.right, r, false); + } + None => () + } + } + + #[test] + fn test_rand_int() { + let mut map: TreeMap = TreeMap::new(); + let mut ctrl = vec![]; + + check_equal(ctrl.as_slice(), &map); + assert!(map.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::>(); + let keys = map.keys().map(|&k| k).collect::>(); + assert_eq!(keys.len(), 3); + assert!(keys.contains(&1)); + assert!(keys.contains(&2)); + assert!(keys.contains(&3)); + } + + #[test] + fn test_values() { + let vec = vec![(1i, 'a'), (2i, 'b'), (3i, 'c')]; + let map = vec.into_iter().collect::>(); + let values = map.values().map(|&v| v).collect::>(); + assert_eq!(values.len(), 3); + assert!(values.contains(&'a')); + assert!(values.contains(&'b')); + assert!(values.contains(&'c')); + } + + #[test] + fn test_eq() { + let mut a = TreeMap::new(); + let mut b = TreeMap::new(); + + assert!(a == b); + assert!(a.insert(0i, 5i)); + 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 = TreeMap::new(); + let empty: TreeMap = TreeMap::new(); + + map.insert(1, 2); + map.insert(3, 4); + + let map_str = format!("{}", map); + + assert!(map_str == "{1: 2, 3: 4}".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 = 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 = TreeMap::new(); + + map.insert(1, 2); + map.insert(2, 1); + map.insert(3, 4); + + assert_eq!(map[2], 1); + } + + #[test] + #[should_fail] + fn test_index_nonexistent() { + let mut map: TreeMap = TreeMap::new(); + + map.insert(1, 2); + map.insert(2, 1); + map.insert(3, 4); + + map[4]; + } + + #[test] + fn test_swap() { + let mut m = TreeMap::new(); + assert_eq!(m.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 = TreeMap::new(); + insert_rand_n(100, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.remove(&i); }); + } + + #[bench] + pub fn insert_rand_10_000(b: &mut Bencher) { + let mut m : TreeMap = TreeMap::new(); + insert_rand_n(10_000, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.remove(&i); }); + } + + // Insert seq + #[bench] + pub fn insert_seq_100(b: &mut Bencher) { + let mut m : TreeMap = TreeMap::new(); + insert_seq_n(100, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.remove(&i); }); + } + + #[bench] + pub fn insert_seq_10_000(b: &mut Bencher) { + let mut m : TreeMap = TreeMap::new(); + insert_seq_n(10_000, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.remove(&i); }); + } + + // Find rand + #[bench] + pub fn find_rand_100(b: &mut Bencher) { + let mut m : TreeMap = TreeMap::new(); + find_rand_n(100, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.find(&i); }); + } + + #[bench] + pub fn find_rand_10_000(b: &mut Bencher) { + let mut m : TreeMap = TreeMap::new(); + find_rand_n(10_000, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.find(&i); }); + } + + // Find seq + #[bench] + pub fn find_seq_100(b: &mut Bencher) { + let mut m : TreeMap = TreeMap::new(); + find_seq_n(100, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.find(&i); }); + } + + #[bench] + pub fn find_seq_10_000(b: &mut Bencher) { + let mut m : TreeMap = TreeMap::new(); + find_seq_n(10_000, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.find(&i); }); + } + + fn bench_iter(b: &mut Bencher, size: uint) { + let mut map = TreeMap::::new(); + let mut rng = weak_rng(); + + for _ in range(0, size) { + map.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); + } +} + diff --git a/src/libcollections/tree/mod.rs b/src/libcollections/tree/mod.rs new file mode 100644 index 00000000000..ac8279c92fe --- /dev/null +++ b/src/libcollections/tree/mod.rs @@ -0,0 +1,36 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Maps are collections of unique keys with corresponding values, and sets are +//! just unique keys without a corresponding value. 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 diff --git a/src/libcollections/tree/set.rs b/src/libcollections/tree/set.rs new file mode 100644 index 00000000000..d24a8234b20 --- /dev/null +++ b/src/libcollections/tree/set.rs @@ -0,0 +1,950 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use core::prelude::*; + +use core::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 { +/// Some(self.cmp(other)) +/// } +/// } +/// +/// let mut trolls = TreeSet::new(); +/// +/// trolls.insert(Troll { name: "Orgarr", level: 2 }); +/// trolls.insert(Troll { name: "Blargarr", level: 3 }); +/// trolls.insert(Troll { name: "Kron the Smelly One", level: 4 }); +/// trolls.insert(Troll { name: "Wartilda", level: 1 }); +/// +/// println!("You are facing {} trolls!", trolls.len()); +/// +/// // Print the trolls, ordered by level with smallest level first +/// for x in trolls.iter() { +/// println!("level {}: {}!", x.level, x.name); +/// } +/// +/// // Kill all trolls +/// trolls.clear(); +/// assert_eq!(trolls.len(), 0); +/// ``` +#[deriving(Clone)] +pub struct TreeSet { + map: TreeMap +} + +impl PartialEq for TreeSet { + #[inline] + fn eq(&self, other: &TreeSet) -> bool { self.map == other.map } +} + +impl Eq for TreeSet {} + +impl PartialOrd for TreeSet { + #[inline] + fn partial_cmp(&self, other: &TreeSet) -> Option { + self.map.partial_cmp(&other.map) + } +} + +impl Ord for TreeSet { + #[inline] + fn cmp(&self, other: &TreeSet) -> Ordering { + iter::order::cmp(self.iter(), other.iter()) + } +} + +impl Show for TreeSet { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + try!(write!(f, "{{")); + + for (i, x) in self.iter().enumerate() { + if i != 0 { try!(write!(f, ", ")); } + try!(write!(f, "{}", *x)); + } + + write!(f, "}}") + } +} + +impl Default for TreeSet { + #[inline] + fn default() -> TreeSet { TreeSet::new() } +} + +impl TreeSet { + /// Creates an empty `TreeSet`. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeSet; + /// let mut set: TreeSet = TreeSet::new(); + /// ``` + #[inline] + pub fn new() -> TreeSet { 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 = [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 = [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 = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect(); + /// + /// // Not possible with a regular `.iter()` + /// let v: Vec = set.into_iter().collect(); + /// assert_eq!(v, vec![1, 2, 3, 4, 5]); + /// ``` + #[inline] + pub fn into_iter(self) -> MoveSetItems { + 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 = [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 = [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 = [1, 2, 3].iter().map(|&x| x).collect(); + /// let b: TreeSet = [3, 4, 5].iter().map(|&x| x).collect(); + /// + /// // Can be seen as `a - b`. + /// for x in a.difference(&b) { + /// println!("{}", x); // Print 1 then 2 + /// } + /// + /// let diff: TreeSet = a.difference(&b).map(|&x| x).collect(); + /// assert_eq!(diff, [1, 2].iter().map(|&x| x).collect()); + /// + /// // Note that difference is not symmetric, + /// // and `b - a` means something else: + /// let diff: TreeSet = b.difference(&a).map(|&x| x).collect(); + /// assert_eq!(diff, [4, 5].iter().map(|&x| x).collect()); + /// ``` + pub fn difference<'a>(&'a self, other: &'a TreeSet) -> DifferenceItems<'a, T> { + DifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} + } + + /// Visits the values representing the symmetric difference, in ascending order. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeSet; + /// + /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); + /// let b: TreeSet = [3, 4, 5].iter().map(|&x| x).collect(); + /// + /// // Print 1, 2, 4, 5 in ascending order. + /// for x in a.symmetric_difference(&b) { + /// println!("{}", x); + /// } + /// + /// let diff1: TreeSet = a.symmetric_difference(&b).map(|&x| x).collect(); + /// let diff2: TreeSet = b.symmetric_difference(&a).map(|&x| x).collect(); + /// + /// assert_eq!(diff1, diff2); + /// assert_eq!(diff1, [1, 2, 4, 5].iter().map(|&x| x).collect()); + /// ``` + pub fn symmetric_difference<'a>(&'a self, other: &'a TreeSet) + -> SymDifferenceItems<'a, T> { + SymDifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} + } + + /// Visits the values representing the intersection, in ascending order. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeSet; + /// + /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); + /// let b: TreeSet = [2, 3, 4].iter().map(|&x| x).collect(); + /// + /// // Print 2, 3 in ascending order. + /// for x in a.intersection(&b) { + /// println!("{}", x); + /// } + /// + /// let diff: TreeSet = a.intersection(&b).map(|&x| x).collect(); + /// assert_eq!(diff, [2, 3].iter().map(|&x| x).collect()); + /// ``` + pub fn intersection<'a>(&'a self, other: &'a TreeSet) + -> IntersectionItems<'a, T> { + IntersectionItems{a: self.iter().peekable(), b: other.iter().peekable()} + } + + /// Visits the values representing the union, in ascending order. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeSet; + /// + /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); + /// let b: TreeSet = [3, 4, 5].iter().map(|&x| x).collect(); + /// + /// // Print 1, 2, 3, 4, 5 in ascending order. + /// for x in a.union(&b) { + /// println!("{}", x); + /// } + /// + /// let diff: TreeSet = a.union(&b).map(|&x| x).collect(); + /// assert_eq!(diff, [1, 2, 3, 4, 5].iter().map(|&x| x).collect()); + /// ``` + pub fn union<'a>(&'a self, other: &'a TreeSet) -> UnionItems<'a, T> { + UnionItems{a: self.iter().peekable(), b: other.iter().peekable()} + } + + /// Return the number of elements in the set + /// + /// # 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 = [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 = [1i, 2, 3].iter().map(|&x| x).collect(); + /// let mut b: TreeSet = TreeSet::new(); + /// + /// assert_eq!(a.is_disjoint(&b), true); + /// b.insert(4); + /// assert_eq!(a.is_disjoint(&b), true); + /// b.insert(1); + /// assert_eq!(a.is_disjoint(&b), false); + /// ``` + pub fn is_disjoint(&self, other: &TreeSet) -> 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 = [1i, 2, 3].iter().map(|&x| x).collect(); + /// let mut set: TreeSet = TreeSet::new(); + /// + /// assert_eq!(set.is_subset(&sup), true); + /// set.insert(2); + /// assert_eq!(set.is_subset(&sup), true); + /// set.insert(4); + /// assert_eq!(set.is_subset(&sup), false); + /// ``` + pub fn is_subset(&self, other: &TreeSet) -> bool { + let mut x = self.iter(); + let mut y = other.iter(); + let mut a = x.next(); + let mut b = y.next(); + while a.is_some() { + if b.is_none() { + return false; + } + + let a1 = a.unwrap(); + let b1 = b.unwrap(); + + match b1.cmp(a1) { + Less => (), + Greater => return false, + Equal => a = x.next(), + } + + b = y.next(); + } + true + } + + /// Returns `true` if the set is a superset of another. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeSet; + /// + /// let sub: TreeSet = [1i, 2].iter().map(|&x| x).collect(); + /// let mut set: TreeSet = TreeSet::new(); + /// + /// assert_eq!(set.is_superset(&sub), false); + /// + /// set.insert(0); + /// set.insert(1); + /// assert_eq!(set.is_superset(&sub), false); + /// + /// set.insert(2); + /// assert_eq!(set.is_superset(&sub), true); + /// ``` + pub fn is_superset(&self, other: &TreeSet) -> bool { + other.is_subset(self) + } + + /// Adds a value to the set. Returns `true` if the value was not already + /// present in the set. + /// + /// # 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 = iter::Map<'static, (T, ()), T, MoveEntries>; + +/// A lazy iterator producing elements in the set difference (in-order). +pub struct DifferenceItems<'a, T:'a> { + a: Peekable<&'a T, SetItems<'a, T>>, + b: Peekable<&'a T, SetItems<'a, T>>, +} + +/// A lazy iterator producing elements in the set symmetric difference (in-order). +pub struct SymDifferenceItems<'a, T:'a> { + a: Peekable<&'a T, SetItems<'a, T>>, + b: Peekable<&'a T, SetItems<'a, T>>, +} + +/// A lazy iterator producing elements in the set intersection (in-order). +pub struct IntersectionItems<'a, T:'a> { + a: Peekable<&'a T, SetItems<'a, T>>, + b: Peekable<&'a T, SetItems<'a, T>>, +} + +/// A lazy iterator producing elements in the set union (in-order). +pub struct UnionItems<'a, T:'a> { + a: Peekable<&'a T, SetItems<'a, T>>, + b: Peekable<&'a T, SetItems<'a, T>>, +} + +/// Compare `x` and `y`, but return `short` if x is None and `long` if y is None +fn cmp_opt(x: Option<&T>, y: Option<&T>, + short: Ordering, long: Ordering) -> Ordering { + match (x, y) { + (None , _ ) => short, + (_ , None ) => long, + (Some(x1), Some(y1)) => x1.cmp(y1), + } +} + + +impl<'a, T> Iterator<&'a T> for SetItems<'a, T> { + #[inline] + fn next(&mut self) -> Option<&'a T> { + self.iter.next().map(|(value, _)| value) + } +} + +impl<'a, T> Iterator<&'a T> for RevSetItems<'a, T> { + #[inline] + fn next(&mut self) -> Option<&'a T> { + self.iter.next().map(|(value, _)| value) + } +} + +impl<'a, T: Ord> Iterator<&'a T> for DifferenceItems<'a, T> { + fn next(&mut self) -> Option<&'a T> { + loop { + match cmp_opt(self.a.peek(), self.b.peek(), Less, Less) { + Less => return self.a.next(), + Equal => { self.a.next(); self.b.next(); } + Greater => { self.b.next(); } + } + } + } +} + +impl<'a, T: Ord> Iterator<&'a T> for SymDifferenceItems<'a, T> { + fn next(&mut self) -> Option<&'a T> { + loop { + match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) { + Less => return self.a.next(), + Equal => { self.a.next(); self.b.next(); } + Greater => return self.b.next(), + } + } + } +} + +impl<'a, T: Ord> Iterator<&'a T> for IntersectionItems<'a, T> { + fn next(&mut self) -> Option<&'a T> { + loop { + let o_cmp = match (self.a.peek(), self.b.peek()) { + (None , _ ) => None, + (_ , None ) => None, + (Some(a1), Some(b1)) => Some(a1.cmp(b1)), + }; + match o_cmp { + None => return None, + Some(Less) => { self.a.next(); } + Some(Equal) => { self.b.next(); return self.a.next() } + Some(Greater) => { self.b.next(); } + } + } + } +} + +impl<'a, T: Ord> Iterator<&'a T> for UnionItems<'a, T> { + fn next(&mut self) -> Option<&'a T> { + loop { + match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) { + Less => return self.a.next(), + Equal => { self.b.next(); return self.a.next() } + Greater => return self.b.next(), + } + } + } +} + +impl FromIterator for TreeSet { + fn from_iter>(iter: Iter) -> TreeSet { + let mut set = TreeSet::new(); + set.extend(iter); + set + } +} + +impl Extendable for TreeSet { + #[inline] + fn extend>(&mut self, mut iter: Iter) { + for elem in iter { + self.insert(elem); + } + } +} + +impl> Hash for TreeSet { + fn hash(&self, state: &mut S) { + for elt in self.iter() { + elt.hash(state); + } + } +} + +#[cfg(test)] +mod test { + use std::prelude::*; + use std::hash; + + use super::TreeSet; + + #[test] + fn test_clear() { + let mut s = TreeSet::new(); + s.clear(); + assert!(s.insert(5i)); + assert!(s.insert(12)); + assert!(s.insert(19)); + s.clear(); + assert!(!s.contains(&5)); + assert!(!s.contains(&12)); + assert!(!s.contains(&19)); + assert!(s.is_empty()); + } + + #[test] + fn test_disjoint() { + let mut xs = TreeSet::new(); + let mut ys = TreeSet::new(); + assert!(xs.is_disjoint(&ys)); + assert!(ys.is_disjoint(&xs)); + assert!(xs.insert(5i)); + assert!(ys.insert(11i)); + assert!(xs.is_disjoint(&ys)); + assert!(ys.is_disjoint(&xs)); + assert!(xs.insert(7)); + assert!(xs.insert(19)); + assert!(xs.insert(4)); + assert!(ys.insert(2)); + assert!(ys.insert(-11)); + assert!(xs.is_disjoint(&ys)); + assert!(ys.is_disjoint(&xs)); + assert!(ys.insert(7)); + assert!(!xs.is_disjoint(&ys)); + assert!(!ys.is_disjoint(&xs)); + } + + #[test] + fn test_subset_and_superset() { + let mut a = TreeSet::new(); + assert!(a.insert(0i)); + assert!(a.insert(5)); + assert!(a.insert(11)); + assert!(a.insert(7)); + + let mut b = TreeSet::new(); + assert!(b.insert(0i)); + assert!(b.insert(7)); + assert!(b.insert(19)); + assert!(b.insert(250)); + assert!(b.insert(11)); + assert!(b.insert(200)); + + assert!(!a.is_subset(&b)); + assert!(!a.is_superset(&b)); + assert!(!b.is_subset(&a)); + assert!(!b.is_superset(&a)); + + assert!(b.insert(5)); + + assert!(a.is_subset(&b)); + assert!(!a.is_superset(&b)); + assert!(!b.is_subset(&a)); + assert!(b.is_superset(&a)); + } + + #[test] + fn test_iterator() { + let mut m = TreeSet::new(); + + assert!(m.insert(3i)); + assert!(m.insert(0)); + assert!(m.insert(4)); + assert!(m.insert(2)); + assert!(m.insert(1)); + + let mut n = 0; + for x in m.iter() { + assert_eq!(*x, n); + n += 1 + } + } + + #[test] + fn test_rev_iter() { + let mut m = TreeSet::new(); + + assert!(m.insert(3i)); + assert!(m.insert(0)); + assert!(m.insert(4)); + assert!(m.insert(2)); + assert!(m.insert(1)); + + let mut n = 4; + for x in m.rev_iter() { + assert_eq!(*x, n); + n -= 1; + } + } + + #[test] + fn test_move_iter() { + let s: TreeSet = range(0i, 5).collect(); + + let mut n = 0; + for x in s.into_iter() { + assert_eq!(x, n); + n += 1; + } + } + + #[test] + fn test_move_iter_size_hint() { + let s: TreeSet = vec!(0i, 1).into_iter().collect(); + + let mut it = s.into_iter(); + + assert_eq!(it.size_hint(), (2, Some(2))); + assert!(it.next() != None); + + assert_eq!(it.size_hint(), (1, Some(1))); + assert!(it.next() != None); + + assert_eq!(it.size_hint(), (0, Some(0))); + assert_eq!(it.next(), None); + } + + #[test] + fn test_clone_eq() { + let mut m = TreeSet::new(); + + m.insert(1i); + m.insert(2); + + assert!(m.clone() == m); + } + + #[test] + fn test_hash() { + let mut x = TreeSet::new(); + let mut y = TreeSet::new(); + + x.insert(1i); + x.insert(2); + x.insert(3); + + y.insert(3i); + y.insert(2); + y.insert(1); + + assert!(hash::hash(&x) == hash::hash(&y)); + } + + fn check(a: &[int], + b: &[int], + expected: &[int], + f: |&TreeSet, &TreeSet, 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 = xs.iter().map(|&x| x).collect(); + + for x in xs.iter() { + assert!(set.contains(x)); + } + } + + #[test] + fn test_show() { + let mut set: TreeSet = TreeSet::new(); + let empty: TreeSet = TreeSet::new(); + + set.insert(1); + set.insert(2); + + let set_str = format!("{}", set); + + assert!(set_str == "{1, 2}".to_string()); + assert_eq!(format!("{}", empty), "{}".to_string()); + } +} diff --git a/src/libcollections/treemap.rs b/src/libcollections/treemap.rs deleted file mode 100644 index 7e6efcb3d12..00000000000 --- a/src/libcollections/treemap.rs +++ /dev/null @@ -1,2867 +0,0 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! 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 { -/// Some(self.cmp(other)) -/// } -/// } -/// -/// // Use a map to store trolls, sorted by level, and track a list of -/// // heroes slain. -/// let mut trolls = TreeMap::new(); -/// -/// trolls.insert(Troll { name: "Orgarr", level: 2 }, -/// vec!["King Karl"]); -/// trolls.insert(Troll { name: "Blargarr", level: 3 }, -/// vec!["Odd"]); -/// trolls.insert(Troll { name: "Kron the Smelly One", level: 4 }, -/// vec!["Omar the Brave", "Peter: Slayer of Trolls"]); -/// trolls.insert(Troll { name: "Wartilda", level: 1 }, -/// vec![]); -/// -/// println!("You are facing {} trolls!", trolls.len()); -/// -/// // Print the trolls, ordered by level with smallest level first -/// for (troll, heroes) in trolls.iter() { -/// let what = if heroes.len() == 1u { "hero" } -/// else { "heroes" }; -/// -/// println!("level {}: '{}' has slain {} {}", -/// troll.level, troll.name, heroes.len(), what); -/// } -/// -/// // Kill all trolls -/// trolls.clear(); -/// assert_eq!(trolls.len(), 0); -/// ``` - -// Future improvements: - -// range search - O(log n) retrieval of an iterator from some key - -// (possibly) implement the overloads Python does for sets: -// * intersection: & -// * difference: - -// * symmetric difference: ^ -// * union: | -// These would be convenient since the methods work like `each` - -#[deriving(Clone)] -pub struct TreeMap { - root: Option>>, - length: uint -} - -impl PartialEq for TreeMap { - fn eq(&self, other: &TreeMap) -> bool { - self.len() == other.len() && - self.iter().zip(other.iter()).all(|(a, b)| a == b) - } -} - -impl Eq for TreeMap {} - -impl PartialOrd for TreeMap { - #[inline] - fn partial_cmp(&self, other: &TreeMap) -> Option { - iter::order::partial_cmp(self.iter(), other.iter()) - } -} - -impl Ord for TreeMap { - #[inline] - fn cmp(&self, other: &TreeMap) -> Ordering { - iter::order::cmp(self.iter(), other.iter()) - } -} - -impl Show for TreeMap { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{{")); - - for (i, (k, v)) in self.iter().enumerate() { - if i != 0 { try!(write!(f, ", ")); } - try!(write!(f, "{}: {}", *k, *v)); - } - - write!(f, "}}") - } -} - -impl Default for TreeMap { - #[inline] - fn default() -> TreeMap { TreeMap::new() } -} - -impl Index for TreeMap { - #[inline] - fn index<'a>(&'a self, i: &K) -> &'a V { - self.find(i).expect("no entry found for key") - } -} - -impl IndexMut for TreeMap { - #[inline] - fn index_mut<'a>(&'a mut self, i: &K) -> &'a mut V { - self.find_mut(i).expect("no entry found for key") - } -} - -impl TreeMap { - /// Creates an empty `TreeMap`. - /// - /// # Example - /// - /// ``` - /// use std::collections::TreeMap; - /// let mut map: TreeMap<&str, int> = TreeMap::new(); - /// ``` - pub fn new() -> TreeMap { 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 { - 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 { - 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 { - let ret = remove(&mut self.root, key); - if ret.is_some() { self.length -= 1 } - ret - } -} - -impl TreeMap { - /// Returns the value for which `f(key)` returns `Equal`. `f` is invoked - /// with current key and guides tree navigation. That means `f` should - /// be aware of natural ordering of the tree. - /// - /// # Example - /// - /// ``` - /// use collections::treemap::TreeMap; - /// - /// fn get_headers() -> TreeMap { - /// let mut result = TreeMap::new(); - /// result.insert("Content-Type".to_string(), "application/xml".to_string()); - /// result.insert("User-Agent".to_string(), "Curl-Rust/0.1".to_string()); - /// result - /// } - /// - /// let headers = get_headers(); - /// let ua_key = "User-Agent"; - /// let ua = headers.find_with(|k| { - /// ua_key.cmp(&k.as_slice()) - /// }); - /// - /// assert_eq!((*ua.unwrap()).as_slice(), "Curl-Rust/0.1"); - /// ``` - #[inline] - 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 TreeMap { - /// Gets a lazy iterator that should be initialized using - /// `traverse_left`/`traverse_right`/`traverse_complete`. - fn iter_for_traversal<'a>(&'a self) -> Entries<'a, K, V> { - Entries { - stack: vec!(), - node: deref(&self.root), - remaining_min: 0, - remaining_max: self.length - } - } - - /// Returns a lazy iterator to the first key-value pair whose key is not less than `k` - /// If all keys in map are less than `k` an empty iterator is returned. - /// - /// # 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>, - // See the comment on MutEntries; this is just to allow - // code-sharing (for this immutable-values iterator it *could* very - // well be Option<&'a TreeNode>). - node: *const TreeNode, - remaining_min: uint, - remaining_max: uint -} - -/// Lazy backward iterator over a map -pub struct RevEntries<'a, K:'a, V:'a> { - iter: Entries<'a, K, V>, -} - -/// Lazy forward iterator over a map that allows for the mutation of -/// the values. -pub struct MutEntries<'a, K:'a, V:'a> { - stack: Vec<&'a mut TreeNode>, - // Unfortunately, we require some unsafe-ness to get around the - // fact that we would be storing a reference *into* one of the - // nodes in the stack. - // - // As far as the compiler knows, this would let us invalidate the - // reference by assigning a new value to this node's position in - // its parent, which would cause this current one to be - // deallocated so this reference would be invalid. (i.e. the - // compilers complaints are 100% correct.) - // - // However, as far as you humans reading this code know (or are - // about to know, if you haven't read far enough down yet), we are - // only reading from the TreeNode.{left,right} fields. the only - // thing that is ever mutated is the .value field (although any - // actual mutation that happens is done externally, by the - // iterator consumer). So, don't be so concerned, rustc, we've got - // it under control. - // - // (This field can legitimately be null.) - node: *mut TreeNode, - remaining_min: uint, - remaining_max: uint -} - -/// Lazy backward iterator over a map -pub struct RevMutEntries<'a, K:'a, V:'a> { - iter: MutEntries<'a, K, V>, -} - -/// TreeMap keys iterator. -pub type Keys<'a, K, V> = - iter::Map<'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 `& ` token -// sequence and forces their evaluation as an expression. -macro_rules! addr { ($e:expr) => { $e }} -// putting an optional mut into type signatures -macro_rules! item { ($i:item) => { $i }} - -macro_rules! define_iterator { - ($name:ident, - $rev_name:ident, - - // the function to go from &m Option> to *m TreeNode - deref = $deref:ident, - - // see comment on `addr!`, this is just an optional `mut`, but - // there's no support for 0-or-1 repeats. - addr_mut = $($addr_mut:tt)* - ) => { - // private methods on the forward iterator (item!() for the - // addr_mut in the next_ return value) - item!(impl<'a, K, V> $name<'a, K, V> { - #[inline(always)] - fn next_(&mut self, forward: bool) -> Option<(&'a K, &'a $($addr_mut)* V)> { - while !self.stack.is_empty() || !self.node.is_null() { - if !self.node.is_null() { - let node = unsafe {addr!(& $($addr_mut)* *self.node)}; - { - let next_node = if forward { - addr!(& $($addr_mut)* node.left) - } else { - addr!(& $($addr_mut)* node.right) - }; - self.node = $deref(next_node); - } - self.stack.push(node); - } else { - let node = self.stack.pop().unwrap(); - let next_node = if forward { - addr!(& $($addr_mut)* node.right) - } else { - addr!(& $($addr_mut)* node.left) - }; - self.node = $deref(next_node); - self.remaining_max -= 1; - if self.remaining_min > 0 { - self.remaining_min -= 1; - } - return Some((&node.key, addr!(& $($addr_mut)* node.value))); - } - } - None - } - - /// traverse_left, traverse_right and traverse_complete are - /// used to initialize Entries/MutEntries - /// pointing to element inside tree structure. - /// - /// They should be used in following manner: - /// - create iterator using TreeMap::[mut_]iter_for_traversal - /// - find required node using `traverse_left`/`traverse_right` - /// (current node is `Entries::node` field) - /// - complete initialization with `traverse_complete` - /// - /// After this, iteration will start from `self.node`. If - /// `self.node` is None iteration will start from last - /// node from which we traversed left. - #[inline] - fn traverse_left(&mut self) { - let node = unsafe {addr!(& $($addr_mut)* *self.node)}; - self.node = $deref(addr!(& $($addr_mut)* node.left)); - self.stack.push(node); - } - - #[inline] - fn traverse_right(&mut self) { - let node = unsafe {addr!(& $($addr_mut)* *self.node)}; - self.node = $deref(addr!(& $($addr_mut)* node.right)); - } - - #[inline] - fn traverse_complete(&mut self) { - if !self.node.is_null() { - unsafe { - self.stack.push(addr!(& $($addr_mut)* *self.node)); - } - self.node = ptr::RawPtr::null(); - } - } - }) - - // the forward Iterator impl. - item!(impl<'a, K, V> Iterator<(&'a K, &'a $($addr_mut)* V)> for $name<'a, K, V> { - /// Advances the iterator to the next node (in order) and return a - /// tuple with a reference to the key and value. If there are no - /// more nodes, return `None`. - fn next(&mut self) -> Option<(&'a K, &'a $($addr_mut)* V)> { - self.next_(true) - } - - #[inline] - fn size_hint(&self) -> (uint, Option) { - (self.remaining_min, Some(self.remaining_max)) - } - }) - - // the reverse Iterator impl. - item!(impl<'a, K, V> Iterator<(&'a K, &'a $($addr_mut)* V)> for $rev_name<'a, K, V> { - fn next(&mut self) -> Option<(&'a K, &'a $($addr_mut)* V)> { - self.iter.next_(false) - } - - #[inline] - fn size_hint(&self) -> (uint, Option) { - self.iter.size_hint() - } - }) - } -} // end of define_iterator - -define_iterator! { - Entries, - RevEntries, - deref = deref, - - // immutable, so no mut - addr_mut = -} -define_iterator! { - MutEntries, - RevMutEntries, - deref = deref_mut, - - addr_mut = mut -} - -fn deref<'a, K, V>(node: &'a Option>>) -> *const TreeNode { - match *node { - Some(ref n) => { - let n: &TreeNode = &**n; - n as *const TreeNode - } - None => ptr::null() - } -} - -fn deref_mut(x: &mut Option>>) - -> *mut TreeNode { - match *x { - Some(ref mut n) => { - let n: &mut TreeNode = &mut **n; - n as *mut TreeNode - } - None => ptr::null_mut() - } -} - -/// Lazy forward iterator over a map that consumes the map while iterating -pub struct MoveEntries { - stack: Vec>, - remaining: uint -} - -impl Iterator<(K, V)> for MoveEntries { - #[inline] - fn next(&mut self) -> Option<(K, V)> { - while !self.stack.is_empty() { - let TreeNode { - key, - value, - left, - right, - level, - } = self.stack.pop().unwrap(); - - match left { - Some(box left) => { - let n = TreeNode { - key: key, - value: value, - left: None, - right: right, - level: level - }; - self.stack.push(n); - self.stack.push(left); - } - None => { - match right { - Some(box right) => self.stack.push(right), - None => () - } - self.remaining -= 1; - return Some((key, value)) - } - } - } - None - } - - #[inline] - fn size_hint(&self) -> (uint, Option) { - (self.remaining, Some(self.remaining)) - } - -} - -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 { -/// Some(self.cmp(other)) -/// } -/// } -/// -/// let mut trolls = TreeSet::new(); -/// -/// trolls.insert(Troll { name: "Orgarr", level: 2 }); -/// trolls.insert(Troll { name: "Blargarr", level: 3 }); -/// trolls.insert(Troll { name: "Kron the Smelly One", level: 4 }); -/// trolls.insert(Troll { name: "Wartilda", level: 1 }); -/// -/// println!("You are facing {} trolls!", trolls.len()); -/// -/// // Print the trolls, ordered by level with smallest level first -/// for x in trolls.iter() { -/// println!("level {}: {}!", x.level, x.name); -/// } -/// -/// // Kill all trolls -/// trolls.clear(); -/// assert_eq!(trolls.len(), 0); -/// ``` -#[deriving(Clone)] -pub struct TreeSet { - map: TreeMap -} - -impl PartialEq for TreeSet { - #[inline] - fn eq(&self, other: &TreeSet) -> bool { self.map == other.map } -} - -impl Eq for TreeSet {} - -impl PartialOrd for TreeSet { - #[inline] - fn partial_cmp(&self, other: &TreeSet) -> Option { - self.map.partial_cmp(&other.map) - } -} - -impl Ord for TreeSet { - #[inline] - fn cmp(&self, other: &TreeSet) -> Ordering { - iter::order::cmp(self.iter(), other.iter()) - } -} - -impl Show for TreeSet { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{{")); - - for (i, x) in self.iter().enumerate() { - if i != 0 { try!(write!(f, ", ")); } - try!(write!(f, "{}", *x)); - } - - write!(f, "}}") - } -} - -impl Default for TreeSet { - #[inline] - fn default() -> TreeSet { TreeSet::new() } -} - -impl TreeSet { - /// Creates an empty `TreeSet`. - /// - /// # Example - /// - /// ``` - /// use std::collections::TreeSet; - /// let mut set: TreeSet = TreeSet::new(); - /// ``` - #[inline] - pub fn new() -> TreeSet { 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 = [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 = [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 = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect(); - /// - /// // Not possible with a regular `.iter()` - /// let v: Vec = set.into_iter().collect(); - /// assert_eq!(v, vec![1, 2, 3, 4, 5]); - /// ``` - #[inline] - pub fn into_iter(self) -> MoveSetItems { - 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 = [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 = [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 = [1, 2, 3].iter().map(|&x| x).collect(); - /// let b: TreeSet = [3, 4, 5].iter().map(|&x| x).collect(); - /// - /// // Can be seen as `a - b`. - /// for x in a.difference(&b) { - /// println!("{}", x); // Print 1 then 2 - /// } - /// - /// let diff: TreeSet = a.difference(&b).map(|&x| x).collect(); - /// assert_eq!(diff, [1, 2].iter().map(|&x| x).collect()); - /// - /// // Note that difference is not symmetric, - /// // and `b - a` means something else: - /// let diff: TreeSet = b.difference(&a).map(|&x| x).collect(); - /// assert_eq!(diff, [4, 5].iter().map(|&x| x).collect()); - /// ``` - pub fn difference<'a>(&'a self, other: &'a TreeSet) -> DifferenceItems<'a, T> { - DifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} - } - - /// Visits the values representing the symmetric difference, in ascending order. - /// - /// # Example - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); - /// let b: TreeSet = [3, 4, 5].iter().map(|&x| x).collect(); - /// - /// // Print 1, 2, 4, 5 in ascending order. - /// for x in a.symmetric_difference(&b) { - /// println!("{}", x); - /// } - /// - /// let diff1: TreeSet = a.symmetric_difference(&b).map(|&x| x).collect(); - /// let diff2: TreeSet = b.symmetric_difference(&a).map(|&x| x).collect(); - /// - /// assert_eq!(diff1, diff2); - /// assert_eq!(diff1, [1, 2, 4, 5].iter().map(|&x| x).collect()); - /// ``` - pub fn symmetric_difference<'a>(&'a self, other: &'a TreeSet) - -> SymDifferenceItems<'a, T> { - SymDifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} - } - - /// Visits the values representing the intersection, in ascending order. - /// - /// # Example - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); - /// let b: TreeSet = [2, 3, 4].iter().map(|&x| x).collect(); - /// - /// // Print 2, 3 in ascending order. - /// for x in a.intersection(&b) { - /// println!("{}", x); - /// } - /// - /// let diff: TreeSet = a.intersection(&b).map(|&x| x).collect(); - /// assert_eq!(diff, [2, 3].iter().map(|&x| x).collect()); - /// ``` - pub fn intersection<'a>(&'a self, other: &'a TreeSet) - -> IntersectionItems<'a, T> { - IntersectionItems{a: self.iter().peekable(), b: other.iter().peekable()} - } - - /// Visits the values representing the union, in ascending order. - /// - /// # Example - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); - /// let b: TreeSet = [3, 4, 5].iter().map(|&x| x).collect(); - /// - /// // Print 1, 2, 3, 4, 5 in ascending order. - /// for x in a.union(&b) { - /// println!("{}", x); - /// } - /// - /// let diff: TreeSet = a.union(&b).map(|&x| x).collect(); - /// assert_eq!(diff, [1, 2, 3, 4, 5].iter().map(|&x| x).collect()); - /// ``` - pub fn union<'a>(&'a self, other: &'a TreeSet) -> UnionItems<'a, T> { - UnionItems{a: self.iter().peekable(), b: other.iter().peekable()} - } - - /// Return the number of elements in the set - /// - /// # 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 = [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 = [1i, 2, 3].iter().map(|&x| x).collect(); - /// let mut b: TreeSet = TreeSet::new(); - /// - /// assert_eq!(a.is_disjoint(&b), true); - /// b.insert(4); - /// assert_eq!(a.is_disjoint(&b), true); - /// b.insert(1); - /// assert_eq!(a.is_disjoint(&b), false); - /// ``` - pub fn is_disjoint(&self, other: &TreeSet) -> 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 = [1i, 2, 3].iter().map(|&x| x).collect(); - /// let mut set: TreeSet = TreeSet::new(); - /// - /// assert_eq!(set.is_subset(&sup), true); - /// set.insert(2); - /// assert_eq!(set.is_subset(&sup), true); - /// set.insert(4); - /// assert_eq!(set.is_subset(&sup), false); - /// ``` - pub fn is_subset(&self, other: &TreeSet) -> bool { - let mut x = self.iter(); - let mut y = other.iter(); - let mut a = x.next(); - let mut b = y.next(); - while a.is_some() { - if b.is_none() { - return false; - } - - let a1 = a.unwrap(); - let b1 = b.unwrap(); - - match b1.cmp(a1) { - Less => (), - Greater => return false, - Equal => a = x.next(), - } - - b = y.next(); - } - true - } - - /// Returns `true` if the set is a superset of another. - /// - /// # Example - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let sub: TreeSet = [1i, 2].iter().map(|&x| x).collect(); - /// let mut set: TreeSet = TreeSet::new(); - /// - /// assert_eq!(set.is_superset(&sub), false); - /// - /// set.insert(0); - /// set.insert(1); - /// assert_eq!(set.is_superset(&sub), false); - /// - /// set.insert(2); - /// assert_eq!(set.is_superset(&sub), true); - /// ``` - pub fn is_superset(&self, other: &TreeSet) -> bool { - other.is_subset(self) - } - - /// Adds a value to the set. Returns `true` if the value was not already - /// present in the set. - /// - /// # 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 = iter::Map<'static, (T, ()), T, MoveEntries>; - -/// A lazy iterator producing elements in the set difference (in-order). -pub struct DifferenceItems<'a, T:'a> { - a: Peekable<&'a T, SetItems<'a, T>>, - b: Peekable<&'a T, SetItems<'a, T>>, -} - -/// A lazy iterator producing elements in the set symmetric difference (in-order). -pub struct SymDifferenceItems<'a, T:'a> { - a: Peekable<&'a T, SetItems<'a, T>>, - b: Peekable<&'a T, SetItems<'a, T>>, -} - -/// A lazy iterator producing elements in the set intersection (in-order). -pub struct IntersectionItems<'a, T:'a> { - a: Peekable<&'a T, SetItems<'a, T>>, - b: Peekable<&'a T, SetItems<'a, T>>, -} - -/// A lazy iterator producing elements in the set union (in-order). -pub struct UnionItems<'a, T:'a> { - a: Peekable<&'a T, SetItems<'a, T>>, - b: Peekable<&'a T, SetItems<'a, T>>, -} - -/// Compare `x` and `y`, but return `short` if x is None and `long` if y is None -fn cmp_opt(x: Option<&T>, y: Option<&T>, - short: Ordering, long: Ordering) -> Ordering { - match (x, y) { - (None , _ ) => short, - (_ , None ) => long, - (Some(x1), Some(y1)) => x1.cmp(y1), - } -} - -impl<'a, T: 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 { - key: K, - value: V, - left: Option>>, - right: Option>>, - level: uint -} - -impl TreeNode { - /// Creates a new tree node. - #[inline] - pub fn new(key: K, value: V) -> TreeNode { - TreeNode{key: key, value: value, left: None, right: None, level: 1} - } -} - -// Remove left horizontal link by rotating right -fn skew(node: &mut Box>) { - if node.left.as_ref().map_or(false, |x| x.level == node.level) { - let mut save = node.left.take().unwrap(); - swap(&mut node.left, &mut save.right); // save.right now None - swap(node, &mut save); - node.right = Some(save); - } -} - -// Remove dual horizontal link by rotating left and increasing level of -// the parent -fn split(node: &mut Box>) { - if node.right.as_ref().map_or(false, - |x| x.right.as_ref().map_or(false, |y| y.level == node.level)) { - let mut save = node.right.take().unwrap(); - swap(&mut node.right, &mut save.left); // save.left now None - save.level += 1; - swap(node, &mut save); - node.left = Some(save); - } -} - -// Next 2 functions have the same convention: comparator gets -// at input current key and returns search_key cmp cur_key -// (i.e. search_key.cmp(&cur_key)) -fn tree_find_with<'r, K, V>(node: &'r Option>>, - f: |&K| -> Ordering) -> Option<&'r V> { - let mut current: &'r Option>> = node; - loop { - match *current { - Some(ref r) => { - match f(&r.key) { - Less => current = &r.left, - Greater => current = &r.right, - Equal => return Some(&r.value) - } - } - None => return None - } - } -} - -// See comments above tree_find_with -fn tree_find_with_mut<'r, K, V>(node: &'r mut Option>>, - 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(node: &mut Option>>, - key: K, value: V) -> Option { - match *node { - Some(ref mut save) => { - match key.cmp(&save.key) { - Less => { - let inserted = insert(&mut save.left, key, value); - skew(save); - split(save); - inserted - } - Greater => { - let inserted = insert(&mut save.right, key, value); - skew(save); - split(save); - inserted - } - Equal => { - save.key = key; - Some(replace(&mut save.value, value)) - } - } - } - None => { - *node = Some(box TreeNode::new(key, value)); - None - } - } -} - -fn remove(node: &mut Option>>, - key: &K) -> Option { - fn heir_swap(node: &mut Box>, - child: &mut Option>>) { - // *could* be done without recursion, but it won't borrow check - for x in child.iter_mut() { - if x.right.is_some() { - heir_swap(node, &mut x.right); - } else { - swap(&mut node.key, &mut x.key); - swap(&mut node.value, &mut x.value); - } - } - } - - match *node { - None => { - return None; // bottom of tree - } - Some(ref mut save) => { - let (ret, rebalance) = match key.cmp(&save.key) { - Less => (remove(&mut save.left, key), true), - Greater => (remove(&mut save.right, key), true), - Equal => { - if save.left.is_some() { - if save.right.is_some() { - let mut left = save.left.take().unwrap(); - if left.right.is_some() { - heir_swap(save, &mut left.right); - } else { - swap(&mut save.key, &mut left.key); - swap(&mut save.value, &mut left.value); - } - save.left = Some(left); - (remove(&mut save.left, key), true) - } else { - let new = save.left.take().unwrap(); - let box TreeNode{value, ..} = replace(save, new); - *save = save.left.take().unwrap(); - (Some(value), true) - } - } else if save.right.is_some() { - let new = save.right.take().unwrap(); - let box TreeNode{value, ..} = replace(save, new); - (Some(value), true) - } else { - (None, false) - } - } - }; - - if rebalance { - let left_level = save.left.as_ref().map_or(0, |x| x.level); - let right_level = save.right.as_ref().map_or(0, |x| x.level); - - // re-balance, if necessary - if left_level < save.level - 1 || right_level < save.level - 1 { - save.level -= 1; - - if right_level > save.level { - let save_level = save.level; - for x in save.right.iter_mut() { x.level = save_level } - } - - skew(save); - - for right in save.right.iter_mut() { - skew(right); - for x in right.right.iter_mut() { skew(x) } - } - - split(save); - for x in save.right.iter_mut() { split(x) } - } - - return ret; - } - } - } - return match node.take() { - Some(box TreeNode{value, ..}) => Some(value), None => panic!() - }; -} - -impl FromIterator<(K, V)> for TreeMap { - fn from_iter>(iter: T) -> TreeMap { - let mut map = TreeMap::new(); - map.extend(iter); - map - } -} - -impl Extendable<(K, V)> for TreeMap { - #[inline] - fn extend>(&mut self, mut iter: T) { - for (k, v) in iter { - self.insert(k, v); - } - } -} - -impl, V: Hash> Hash for TreeMap { - fn hash(&self, state: &mut S) { - for elt in self.iter() { - elt.hash(state); - } - } -} - -impl FromIterator for TreeSet { - fn from_iter>(iter: Iter) -> TreeSet { - let mut set = TreeSet::new(); - set.extend(iter); - set - } -} - -impl Extendable for TreeSet { - #[inline] - fn extend>(&mut self, mut iter: Iter) { - for elem in iter { - self.insert(elem); - } - } -} - -impl> Hash for TreeSet { - fn hash(&self, state: &mut S) { - for elt in self.iter() { - elt.hash(state); - } - } -} - -#[cfg(test)] -mod test_treemap { - use std::prelude::*; - use std::rand::Rng; - use std::rand; - - use super::{TreeMap, TreeNode}; - - #[test] - fn find_empty() { - let m: TreeMap = TreeMap::new(); - assert!(m.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(ctrl: &[(K, V)], - map: &TreeMap) { - assert_eq!(ctrl.is_empty(), map.is_empty()); - for x in ctrl.iter() { - let &(ref k, ref v) = x; - assert!(map.find(k).unwrap() == v) - } - for (map_k, map_v) in map.iter() { - let mut found = false; - for x in ctrl.iter() { - let &(ref ctrl_k, ref ctrl_v) = x; - if *map_k == *ctrl_k { - assert!(*map_v == *ctrl_v); - found = true; - break; - } - } - assert!(found); - } - } - - fn check_left(node: &Option>>, - parent: &Box>) { - match *node { - Some(ref r) => { - assert_eq!(r.key.cmp(&parent.key), Less); - assert!(r.level == parent.level - 1); // left is black - check_left(&r.left, r); - check_right(&r.right, r, false); - } - None => assert!(parent.level == 1) // parent is leaf - } - } - - fn check_right(node: &Option>>, - parent: &Box>, - parent_red: bool) { - match *node { - Some(ref r) => { - assert_eq!(r.key.cmp(&parent.key), Greater); - let red = r.level == parent.level; - if parent_red { assert!(!red) } // no dual horizontal links - // Right red or black - assert!(red || r.level == parent.level - 1); - check_left(&r.left, r); - check_right(&r.right, r, red); - } - None => assert!(parent.level == 1) // parent is leaf - } - } - - fn check_structure(map: &TreeMap) { - match map.root { - Some(ref r) => { - check_left(&r.left, r); - check_right(&r.right, r, false); - } - None => () - } - } - - #[test] - fn test_rand_int() { - let mut map: TreeMap = TreeMap::new(); - let mut ctrl = vec![]; - - check_equal(ctrl.as_slice(), &map); - assert!(map.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::>(); - let keys = map.keys().map(|&k| k).collect::>(); - assert_eq!(keys.len(), 3); - assert!(keys.contains(&1)); - assert!(keys.contains(&2)); - assert!(keys.contains(&3)); - } - - #[test] - fn test_values() { - let vec = vec![(1i, 'a'), (2i, 'b'), (3i, 'c')]; - let map = vec.into_iter().collect::>(); - let values = map.values().map(|&v| v).collect::>(); - assert_eq!(values.len(), 3); - assert!(values.contains(&'a')); - assert!(values.contains(&'b')); - assert!(values.contains(&'c')); - } - - #[test] - fn test_eq() { - let mut a = TreeMap::new(); - let mut b = TreeMap::new(); - - assert!(a == b); - assert!(a.insert(0i, 5i)); - 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 = TreeMap::new(); - let empty: TreeMap = TreeMap::new(); - - map.insert(1, 2); - map.insert(3, 4); - - let map_str = format!("{}", map); - - assert!(map_str == "{1: 2, 3: 4}".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 = 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 = TreeMap::new(); - - map.insert(1, 2); - map.insert(2, 1); - map.insert(3, 4); - - assert_eq!(map[2], 1); - } - - #[test] - #[should_fail] - fn test_index_nonexistent() { - let mut map: TreeMap = TreeMap::new(); - - map.insert(1, 2); - map.insert(2, 1); - map.insert(3, 4); - - map[4]; - } -} - -#[cfg(test)] -mod bench { - use std::prelude::*; - use std::rand::{weak_rng, Rng}; - use test::{Bencher, black_box}; - - use super::TreeMap; - use bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n}; - - #[bench] - pub fn insert_rand_100(b: &mut Bencher) { - let mut m : TreeMap = TreeMap::new(); - insert_rand_n(100, &mut m, b, - |m, i| { m.insert(i, 1); }, - |m, i| { m.remove(&i); }); - } - - #[bench] - pub fn insert_rand_10_000(b: &mut Bencher) { - let mut m : TreeMap = TreeMap::new(); - insert_rand_n(10_000, &mut m, b, - |m, i| { m.insert(i, 1); }, - |m, i| { m.remove(&i); }); - } - - // Insert seq - #[bench] - pub fn insert_seq_100(b: &mut Bencher) { - let mut m : TreeMap = TreeMap::new(); - insert_seq_n(100, &mut m, b, - |m, i| { m.insert(i, 1); }, - |m, i| { m.remove(&i); }); - } - - #[bench] - pub fn insert_seq_10_000(b: &mut Bencher) { - let mut m : TreeMap = TreeMap::new(); - insert_seq_n(10_000, &mut m, b, - |m, i| { m.insert(i, 1); }, - |m, i| { m.remove(&i); }); - } - - // Find rand - #[bench] - pub fn find_rand_100(b: &mut Bencher) { - let mut m : TreeMap = TreeMap::new(); - find_rand_n(100, &mut m, b, - |m, i| { m.insert(i, 1); }, - |m, i| { m.find(&i); }); - } - - #[bench] - pub fn find_rand_10_000(b: &mut Bencher) { - let mut m : TreeMap = TreeMap::new(); - find_rand_n(10_000, &mut m, b, - |m, i| { m.insert(i, 1); }, - |m, i| { m.find(&i); }); - } - - // Find seq - #[bench] - pub fn find_seq_100(b: &mut Bencher) { - let mut m : TreeMap = TreeMap::new(); - find_seq_n(100, &mut m, b, - |m, i| { m.insert(i, 1); }, - |m, i| { m.find(&i); }); - } - - #[bench] - pub fn find_seq_10_000(b: &mut Bencher) { - let mut m : TreeMap = TreeMap::new(); - find_seq_n(10_000, &mut m, b, - |m, i| { m.insert(i, 1); }, - |m, i| { m.find(&i); }); - } - - fn bench_iter(b: &mut Bencher, size: uint) { - let mut map = TreeMap::::new(); - let mut rng = weak_rng(); - - for _ in range(0, size) { - map.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 = range(0i, 5).collect(); - - let mut n = 0; - for x in s.into_iter() { - assert_eq!(x, n); - n += 1; - } - } - - #[test] - fn test_move_iter_size_hint() { - let s: TreeSet = vec!(0i, 1).into_iter().collect(); - - let mut it = s.into_iter(); - - assert_eq!(it.size_hint(), (2, Some(2))); - assert!(it.next() != None); - - assert_eq!(it.size_hint(), (1, Some(1))); - assert!(it.next() != None); - - assert_eq!(it.size_hint(), (0, Some(0))); - assert_eq!(it.next(), None); - } - - #[test] - fn test_clone_eq() { - let mut m = TreeSet::new(); - - m.insert(1i); - m.insert(2); - - assert!(m.clone() == m); - } - - #[test] - fn test_hash() { - let mut x = TreeSet::new(); - let mut y = TreeSet::new(); - - x.insert(1i); - x.insert(2); - x.insert(3); - - y.insert(3i); - y.insert(2); - y.insert(1); - - assert!(hash::hash(&x) == hash::hash(&y)); - } - - fn check(a: &[int], - b: &[int], - expected: &[int], - f: |&TreeSet, &TreeSet, 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 = xs.iter().map(|&x| x).collect(); - - for x in xs.iter() { - assert!(set.contains(x)); - } - } - - #[test] - fn test_show() { - let mut set: TreeSet = TreeSet::new(); - let empty: TreeSet = TreeSet::new(); - - set.insert(1); - set.insert(2); - - let set_str = format!("{}", set); - - assert!(set_str == "{1, 2}".to_string()); - assert_eq!(format!("{}", empty), "{}".to_string()); - } -} diff --git a/src/libcollections/trie.rs b/src/libcollections/trie.rs deleted file mode 100644 index 7a8cc5df55a..00000000000 --- a/src/libcollections/trie.rs +++ /dev/null @@ -1,1899 +0,0 @@ -// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! 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 { - Internal(Box>), - 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 { - root: TrieNode, - length: uint -} - -impl PartialEq for TrieMap { - fn eq(&self, other: &TrieMap) -> bool { - self.len() == other.len() && - self.iter().zip(other.iter()).all(|(a, b)| a == b) - } -} - -impl Eq for TrieMap {} - -impl PartialOrd for TrieMap { - #[inline] - fn partial_cmp(&self, other: &TrieMap) -> Option { - iter::order::partial_cmp(self.iter(), other.iter()) - } -} - -impl Ord for TrieMap { - #[inline] - fn cmp(&self, other: &TrieMap) -> Ordering { - iter::order::cmp(self.iter(), other.iter()) - } -} - -impl Show for TrieMap { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{{")); - - for (i, (k, v)) in self.iter().enumerate() { - if i != 0 { try!(write!(f, ", ")); } - try!(write!(f, "{}: {}", k, *v)); - } - - write!(f, "}}") - } -} - -impl Default for TrieMap { - #[inline] - fn default() -> TrieMap { TrieMap::new() } -} - -impl TrieMap { - /// Creates an empty `TrieMap`. - /// - /// # Example - /// - /// ``` - /// use std::collections::TrieMap; - /// let mut map: TrieMap<&str> = TrieMap::new(); - /// ``` - #[inline] - pub fn new() -> TrieMap { - 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 = [(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 = &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 { - 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 { - let ret = remove(&mut self.root.count, - &mut self.root.children[chunk(*key, 0)], - *key, 1); - if ret.is_some() { self.length -= 1 } - ret - } -} - -// FIXME #5846 we want to be able to choose between &x and &mut x -// (with many different `x`) below, so we need to optionally pass mut -// as a tt, but the only thing we can do with a `tt` is pass them to -// other macros, so this takes the `& ` token -// sequence and forces their evaluation as an expression. (see also -// `item!` below.) -macro_rules! addr { ($e:expr) => { $e } } - -macro_rules! bound { - ($iterator_name:ident, - // the current treemap - self = $this:expr, - // the key to look for - key = $key:expr, - // are we looking at the upper bound? - is_upper = $upper:expr, - - // method names for slicing/iterating. - slice_from = $slice_from:ident, - iter = $iter:ident, - - // see the comment on `addr!`, this is just an optional mut, but - // there's no 0-or-1 repeats yet. - mutability = $($mut_:tt)*) => { - { - // # For `mut` - // We need an unsafe pointer here because we are borrowing - // mutable references to the internals of each of these - // mutable nodes, while still using the outer node. - // - // However, we're allowed to flaunt rustc like this because we - // never actually modify the "shape" of the nodes. The only - // place that mutation is can actually occur is of the actual - // values of the TrieMap (as the return value of the - // iterator), i.e. we can never cause a deallocation of any - // 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 - }; - - 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 - }; - (child_id + 1, false) - } - External(stored, _) => { - (if stored < key || ($upper && stored == key) { - child_id + 1 - } else { - child_id - }, true) - } - Nothing => { - (child_id + 1, true) - } - }; - // push to the stack. - it.stack[it.length] = children.$slice_from(&slice_idx).$iter(); - it.length += 1; - if ret { return it } - }) - } - } -} - -impl TrieMap { - // If `upper` is true then returns upper_bound else returns lower_bound. - #[inline] - fn bound<'a>(&'a self, key: uint, upper: bool) -> Entries<'a, T> { - bound!(Entries, self = self, - key = key, is_upper = upper, - slice_from = slice_from_or_fail, iter = iter, - mutability = ) - } - - /// Gets an iterator pointing to the first key-value pair whose key is not less than `key`. - /// If all keys in the map are less than `key` an empty iterator is returned. - /// - /// # 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 FromIterator<(uint, T)> for TrieMap { - fn from_iter>(iter: Iter) -> TrieMap { - let mut map = TrieMap::new(); - map.extend(iter); - map - } -} - -impl Extendable<(uint, T)> for TrieMap { - fn extend>(&mut self, mut iter: Iter) { - for (k, v) in iter { - self.insert(k, v); - } - } -} - -impl> Hash for TrieMap { - fn hash(&self, state: &mut S) { - for elt in self.iter() { - elt.hash(state); - } - } -} - -impl Index for TrieMap { - #[inline] - fn index<'a>(&'a self, i: &uint) -> &'a T { - self.find(i).expect("key not present") - } -} - -impl IndexMut for TrieMap { - #[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 for TrieSet { - fn from_iter>(iter: Iter) -> TrieSet { - let mut set = TrieSet::new(); - set.extend(iter); - set - } -} - -impl Extendable for TrieSet { - fn extend>(&mut self, mut iter: Iter) { - for elem in iter { - self.insert(elem); - } - } -} - -struct TrieNode { - count: uint, - children: [Child, ..SIZE] -} - -impl Clone for TrieNode { - #[inline] - fn clone(&self) -> TrieNode { - 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 TrieNode { - #[inline] - fn new() -> TrieNode { - // 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 TrieNode { - 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, 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(count: &mut uint, child: &mut Child, key: uint, value: T, - idx: uint) -> Option { - // we branch twice to avoid having to do the `replace` when we - // don't need to; this is much faster, especially for keys that - // have long shared prefixes. - match *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(count: &mut uint, child: &mut Child, key: uint, - idx: uint) -> Option { - let (ret, this) = match *child { - External(stored, _) if stored == key => { - match mem::replace(child, Nothing) { - External(_, value) => (Some(value), true), - _ => 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>, .. 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>, .. 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) { - (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 for SetItems<'a> { - fn next(&mut self) -> Option { - self.iter.next().map(|(key, _)| key) - } - - fn size_hint(&self) -> (uint, Option) { - 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(trie: &TrieNode) { - 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 = 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::>(); - let keys = map.keys().collect::>(); - assert_eq!(keys.len(), 3); - assert!(keys.contains(&1)); - assert!(keys.contains(&2)); - assert!(keys.contains(&3)); - } - - #[test] - fn test_values() { - let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; - let map = vec.into_iter().collect::>(); - let values = map.values().map(|&v| v).collect::>(); - assert_eq!(values.len(), 3); - assert!(values.contains(&'a')); - assert!(values.contains(&'b')); - assert!(values.contains(&'c')); - } - - #[test] - fn test_iteration() { - let empty_map : TrieMap = TrieMap::new(); - assert_eq!(empty_map.iter().next(), None); - - let first = uint::MAX - 10000; - let last = uint::MAX; - - let mut map = TrieMap::new(); - for x in range(first, last).rev() { - map.insert(x, x / 2); - } - - let mut i = 0; - for (k, &v) in map.iter() { - assert_eq!(k, first + i); - assert_eq!(v, k / 2); - i += 1; - } - assert_eq!(i, last - first); - } - - #[test] - fn test_mut_iter() { - let mut empty_map : TrieMap = TrieMap::new(); - assert!(empty_map.iter_mut().next().is_none()); - - let first = uint::MAX - 10000; - let last = uint::MAX; - - let mut map = TrieMap::new(); - for x in range(first, last).rev() { - map.insert(x, x / 2); - } - - let mut i = 0; - for (k, v) in map.iter_mut() { - assert_eq!(k, first + i); - *v -= k / 2; - i += 1; - } - assert_eq!(i, last - first); - - assert!(map.iter().all(|(_, &v)| v == 0)); - } - - #[test] - fn test_bound() { - let empty_map : TrieMap = TrieMap::new(); - assert_eq!(empty_map.lower_bound(0).next(), None); - assert_eq!(empty_map.upper_bound(0).next(), None); - - let last = 999u; - let step = 3u; - let value = 42u; - - let mut map : TrieMap = TrieMap::new(); - for x in range_step(0u, last, step) { - assert!(x % step == 0); - map.insert(x, value); - } - - for i in range(0u, last - step) { - let mut lb = map.lower_bound(i); - let mut ub = map.upper_bound(i); - let next_key = i - i % step + step; - let next_pair = (next_key, &value); - if i % step == 0 { - assert_eq!(lb.next(), Some((i, &value))); - } else { - assert_eq!(lb.next(), Some(next_pair)); - } - assert_eq!(ub.next(), Some(next_pair)); - } - - let mut lb = map.lower_bound(last - step); - assert_eq!(lb.next(), Some((last - step, &value))); - let mut ub = map.upper_bound(last - step); - assert_eq!(ub.next(), None); - - for i in range(last - step + 1, last) { - let mut lb = map.lower_bound(i); - assert_eq!(lb.next(), None); - let mut ub = map.upper_bound(i); - assert_eq!(ub.next(), None); - } - } - - #[test] - fn test_mut_bound() { - let empty_map : TrieMap = TrieMap::new(); - assert_eq!(empty_map.lower_bound(0).next(), None); - assert_eq!(empty_map.upper_bound(0).next(), None); - - let mut m_lower = TrieMap::new(); - let mut m_upper = TrieMap::new(); - for i in range(0u, 100) { - m_lower.insert(2 * i, 4 * i); - m_upper.insert(2 * i, 4 * i); - } - - for i in range(0u, 199) { - let mut lb_it = m_lower.lower_bound_mut(i); - let (k, v) = lb_it.next().unwrap(); - let lb = i + i % 2; - assert_eq!(lb, k); - *v -= k; - } - - for i in range(0u, 198) { - let mut ub_it = m_upper.upper_bound_mut(i); - let (k, v) = ub_it.next().unwrap(); - let ub = i + 2 - i % 2; - assert_eq!(ub, k); - *v -= k; - } - - assert!(m_lower.lower_bound_mut(199).next().is_none()); - assert!(m_upper.upper_bound_mut(198).next().is_none()); - - assert!(m_lower.iter().all(|(_, &x)| x == 0)); - assert!(m_upper.iter().all(|(_, &x)| x == 0)); - } - - #[test] - fn test_clone() { - let mut a = TrieMap::new(); - - a.insert(1, 'a'); - a.insert(2, 'b'); - a.insert(3, 'c'); - - assert!(a.clone() == a); - } - - #[test] - fn test_eq() { - let mut a = TrieMap::new(); - let mut b = TrieMap::new(); - - assert!(a == b); - assert!(a.insert(0, 5i)); - 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 = 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::::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::::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::::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::() & 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::() & 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); - } -} diff --git a/src/libcollections/trie/map.rs b/src/libcollections/trie/map.rs new file mode 100644 index 00000000000..27486de6f19 --- /dev/null +++ b/src/libcollections/trie/map.rs @@ -0,0 +1,1460 @@ +// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! 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 { + Internal(Box>), + 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 { + root: TrieNode, + length: uint +} + +impl PartialEq for TrieMap { + fn eq(&self, other: &TrieMap) -> bool { + self.len() == other.len() && + self.iter().zip(other.iter()).all(|(a, b)| a == b) + } +} + +impl Eq for TrieMap {} + +impl PartialOrd for TrieMap { + #[inline] + fn partial_cmp(&self, other: &TrieMap) -> Option { + iter::order::partial_cmp(self.iter(), other.iter()) + } +} + +impl Ord for TrieMap { + #[inline] + fn cmp(&self, other: &TrieMap) -> Ordering { + iter::order::cmp(self.iter(), other.iter()) + } +} + +impl Show for TrieMap { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + try!(write!(f, "{{")); + + for (i, (k, v)) in self.iter().enumerate() { + if i != 0 { try!(write!(f, ", ")); } + try!(write!(f, "{}: {}", k, *v)); + } + + write!(f, "}}") + } +} + +impl Default for TrieMap { + #[inline] + fn default() -> TrieMap { TrieMap::new() } +} + +impl TrieMap { + /// Creates an empty `TrieMap`. + /// + /// # Example + /// + /// ``` + /// use std::collections::TrieMap; + /// let mut map: TrieMap<&str> = TrieMap::new(); + /// ``` + #[inline] + pub fn new() -> TrieMap { + 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 = [(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 = &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 { + 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 { + let ret = remove(&mut self.root.count, + &mut self.root.children[chunk(*key, 0)], + *key, 1); + if ret.is_some() { self.length -= 1 } + ret + } +} + +// FIXME #5846 we want to be able to choose between &x and &mut x +// (with many different `x`) below, so we need to optionally pass mut +// as a tt, but the only thing we can do with a `tt` is pass them to +// other macros, so this takes the `& ` token +// sequence and forces their evaluation as an expression. (see also +// `item!` below.) +macro_rules! addr { ($e:expr) => { $e } } + +macro_rules! bound { + ($iterator_name:ident, + // the current treemap + self = $this:expr, + // the key to look for + key = $key:expr, + // are we looking at the upper bound? + is_upper = $upper:expr, + + // method names for slicing/iterating. + slice_from = $slice_from:ident, + iter = $iter:ident, + + // see the comment on `addr!`, this is just an optional mut, but + // there's no 0-or-1 repeats yet. + mutability = $($mut_:tt)*) => { + { + // # For `mut` + // We need an unsafe pointer here because we are borrowing + // mutable references to the internals of each of these + // mutable nodes, while still using the outer node. + // + // However, we're allowed to flaunt rustc like this because we + // never actually modify the "shape" of the nodes. The only + // place that mutation is can actually occur is of the actual + // values of the TrieMap (as the return value of the + // iterator), i.e. we can never cause a deallocation of any + // 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 + }; + + 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 + }; + (child_id + 1, false) + } + External(stored, _) => { + (if stored < key || ($upper && stored == key) { + child_id + 1 + } else { + child_id + }, true) + } + Nothing => { + (child_id + 1, true) + } + }; + // push to the stack. + it.stack[it.length] = children.$slice_from(&slice_idx).$iter(); + it.length += 1; + if ret { return it } + }) + } + } +} + +impl TrieMap { + // If `upper` is true then returns upper_bound else returns lower_bound. + #[inline] + fn bound<'a>(&'a self, key: uint, upper: bool) -> Entries<'a, T> { + bound!(Entries, self = self, + key = key, is_upper = upper, + slice_from = slice_from_or_fail, iter = iter, + mutability = ) + } + + /// Gets an iterator pointing to the first key-value pair whose key is not less than `key`. + /// If all keys in the map are less than `key` an empty iterator is returned. + /// + /// # 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 FromIterator<(uint, T)> for TrieMap { + fn from_iter>(iter: Iter) -> TrieMap { + let mut map = TrieMap::new(); + map.extend(iter); + map + } +} + +impl Extendable<(uint, T)> for TrieMap { + fn extend>(&mut self, mut iter: Iter) { + for (k, v) in iter { + self.insert(k, v); + } + } +} + +impl> Hash for TrieMap { + fn hash(&self, state: &mut S) { + for elt in self.iter() { + elt.hash(state); + } + } +} + +impl Index for TrieMap { + #[inline] + fn index<'a>(&'a self, i: &uint) -> &'a T { + self.find(i).expect("key not present") + } +} + +impl IndexMut for TrieMap { + #[inline] + fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut T { + self.find_mut(i).expect("key not present") + } +} + +struct TrieNode { + count: uint, + children: [Child, ..SIZE] +} + +impl Clone for TrieNode { + #[inline] + fn clone(&self) -> TrieNode { + 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 TrieNode { + #[inline] + fn new() -> TrieNode { + // 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 TrieNode { + 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, 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(count: &mut uint, child: &mut Child, key: uint, value: T, + idx: uint) -> Option { + // we branch twice to avoid having to do the `replace` when we + // don't need to; this is much faster, especially for keys that + // have long shared prefixes. + match *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(count: &mut uint, child: &mut Child, key: uint, + idx: uint) -> Option { + let (ret, this) = match *child { + External(stored, _) if stored == key => { + match mem::replace(child, Nothing) { + External(_, value) => (Some(value), true), + _ => 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>, .. 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>, .. 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) { + (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(trie: &TrieNode) { + 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 = 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::>(); + let keys = map.keys().collect::>(); + assert_eq!(keys.len(), 3); + assert!(keys.contains(&1)); + assert!(keys.contains(&2)); + assert!(keys.contains(&3)); + } + + #[test] + fn test_values() { + let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; + let map = vec.into_iter().collect::>(); + let values = map.values().map(|&v| v).collect::>(); + assert_eq!(values.len(), 3); + assert!(values.contains(&'a')); + assert!(values.contains(&'b')); + assert!(values.contains(&'c')); + } + + #[test] + fn test_iteration() { + let empty_map : TrieMap = TrieMap::new(); + assert_eq!(empty_map.iter().next(), None); + + let first = uint::MAX - 10000; + let last = uint::MAX; + + let mut map = TrieMap::new(); + for x in range(first, last).rev() { + map.insert(x, x / 2); + } + + let mut i = 0; + for (k, &v) in map.iter() { + assert_eq!(k, first + i); + assert_eq!(v, k / 2); + i += 1; + } + assert_eq!(i, last - first); + } + + #[test] + fn test_mut_iter() { + let mut empty_map : TrieMap = TrieMap::new(); + assert!(empty_map.iter_mut().next().is_none()); + + let first = uint::MAX - 10000; + let last = uint::MAX; + + let mut map = TrieMap::new(); + for x in range(first, last).rev() { + map.insert(x, x / 2); + } + + let mut i = 0; + for (k, v) in map.iter_mut() { + assert_eq!(k, first + i); + *v -= k / 2; + i += 1; + } + assert_eq!(i, last - first); + + assert!(map.iter().all(|(_, &v)| v == 0)); + } + + #[test] + fn test_bound() { + let empty_map : TrieMap = TrieMap::new(); + assert_eq!(empty_map.lower_bound(0).next(), None); + assert_eq!(empty_map.upper_bound(0).next(), None); + + let last = 999u; + let step = 3u; + let value = 42u; + + let mut map : TrieMap = TrieMap::new(); + for x in range_step(0u, last, step) { + assert!(x % step == 0); + map.insert(x, value); + } + + for i in range(0u, last - step) { + let mut lb = map.lower_bound(i); + let mut ub = map.upper_bound(i); + let next_key = i - i % step + step; + let next_pair = (next_key, &value); + if i % step == 0 { + assert_eq!(lb.next(), Some((i, &value))); + } else { + assert_eq!(lb.next(), Some(next_pair)); + } + assert_eq!(ub.next(), Some(next_pair)); + } + + let mut lb = map.lower_bound(last - step); + assert_eq!(lb.next(), Some((last - step, &value))); + let mut ub = map.upper_bound(last - step); + assert_eq!(ub.next(), None); + + for i in range(last - step + 1, last) { + let mut lb = map.lower_bound(i); + assert_eq!(lb.next(), None); + let mut ub = map.upper_bound(i); + assert_eq!(ub.next(), None); + } + } + + #[test] + fn test_mut_bound() { + let empty_map : TrieMap = TrieMap::new(); + assert_eq!(empty_map.lower_bound(0).next(), None); + assert_eq!(empty_map.upper_bound(0).next(), None); + + let mut m_lower = TrieMap::new(); + let mut m_upper = TrieMap::new(); + for i in range(0u, 100) { + m_lower.insert(2 * i, 4 * i); + m_upper.insert(2 * i, 4 * i); + } + + for i in range(0u, 199) { + let mut lb_it = m_lower.lower_bound_mut(i); + let (k, v) = lb_it.next().unwrap(); + let lb = i + i % 2; + assert_eq!(lb, k); + *v -= k; + } + + for i in range(0u, 198) { + let mut ub_it = m_upper.upper_bound_mut(i); + let (k, v) = ub_it.next().unwrap(); + let ub = i + 2 - i % 2; + assert_eq!(ub, k); + *v -= k; + } + + assert!(m_lower.lower_bound_mut(199).next().is_none()); + assert!(m_upper.upper_bound_mut(198).next().is_none()); + + assert!(m_lower.iter().all(|(_, &x)| x == 0)); + assert!(m_upper.iter().all(|(_, &x)| x == 0)); + } + + #[test] + fn test_clone() { + let mut a = TrieMap::new(); + + a.insert(1, 'a'); + a.insert(2, 'b'); + a.insert(3, 'c'); + + assert!(a.clone() == a); + } + + #[test] + fn test_eq() { + let mut a = TrieMap::new(); + let mut b = TrieMap::new(); + + assert!(a == b); + assert!(a.insert(0, 5i)); + 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 = 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::::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::::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::::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::() & 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::() & 0xff_ff, ()); + } + }) + } +} diff --git a/src/libcollections/trie/mod.rs b/src/libcollections/trie/mod.rs new file mode 100644 index 00000000000..f0f8f00a6a0 --- /dev/null +++ b/src/libcollections/trie/mod.rs @@ -0,0 +1,20 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Maps are collections of unique keys with corresponding values, and sets are +//! just unique keys without a corresponding value. 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 diff --git a/src/libcollections/trie/set.rs b/src/libcollections/trie/set.rs new file mode 100644 index 00000000000..ddddd279b04 --- /dev/null +++ b/src/libcollections/trie/set.rs @@ -0,0 +1,457 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use core::prelude::*; + +use core::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 for TrieSet { + fn from_iter>(iter: Iter) -> TrieSet { + let mut set = TrieSet::new(); + set.extend(iter); + set + } +} + +impl Extendable for TrieSet { + fn extend>(&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 for SetItems<'a> { + fn next(&mut self) -> Option { + self.iter.next().map(|(key, _)| key) + } + + fn size_hint(&self) -> (uint, Option) { + 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); + } +} diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs new file mode 100644 index 00000000000..c0bc785126c --- /dev/null +++ b/src/libcollections/vec_map.rs @@ -0,0 +1,1052 @@ +// 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 or the MIT license +// , 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 { + v: Vec>, +} + +impl Default for VecMap { + #[inline] + fn default() -> VecMap { VecMap::new() } +} + +impl Clone for VecMap { + #[inline] + fn clone(&self) -> VecMap { + VecMap { v: self.v.clone() } + } + + #[inline] + fn clone_from(&mut self, source: &VecMap) { + self.v.reserve(source.v.len()); + for (i, w) in self.v.iter_mut().enumerate() { + *w = source.v[i].clone(); + } + } +} + +impl > Hash for VecMap { + fn hash(&self, state: &mut S) { + self.v.hash(state) + } +} + +impl VecMap { + /// Creates an empty `VecMap`. + /// + /// # Example + /// + /// ``` + /// use std::collections::VecMap; + /// let mut map: VecMap<&str> = VecMap::new(); + /// ``` + pub fn new() -> VecMap { 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 { + 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), (uint, V), + Enumerate>>> + { + 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 { + 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 { + if *key >= self.v.len() { + return None; + } + self.v[*key].take() + } +} + +impl VecMap { + /// 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 PartialOrd for VecMap { + #[inline] + fn partial_cmp(&self, other: &VecMap) -> Option { + iter::order::partial_cmp(self.iter(), other.iter()) + } +} + +impl Ord for VecMap { + #[inline] + fn cmp(&self, other: &VecMap) -> Ordering { + iter::order::cmp(self.iter(), other.iter()) + } +} + +impl fmt::Show for VecMap { + 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 FromIterator<(uint, V)> for VecMap { + fn from_iter>(iter: Iter) -> VecMap { + let mut map = VecMap::new(); + map.extend(iter); + map + } +} + +impl Extendable<(uint, V)> for VecMap { + fn extend>(&mut self, mut iter: Iter) { + for (k, v) in iter { + self.insert(k, v); + } + } +} + +impl Index for VecMap { + #[inline] + fn index<'a>(&'a self, i: &uint) -> &'a V { + self.find(i).expect("key not present") + } +} + +impl IndexMut for VecMap { + #[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) { + (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> +} + +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> +} + +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::>(); + 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::>(); + 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::::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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = VecMap::new(); + find_seq_n(10_000, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.find(&i); }); + } +} -- cgit 1.4.1-3-g733a5