511f0b8a3d
This commit aims to prepare the `std::hash` module for alpha by formalizing its current interface whileholding off on adding `#[stable]` to the new APIs. The current usage with the `HashMap` and `HashSet` types is also reconciled by separating out composable parts of the design. The primary goal of this slight redesign is to separate the concepts of a hasher's state from a hashing algorithm itself. The primary change of this commit is to separate the `Hasher` trait into a `Hasher` and a `HashState` trait. Conceptually the old `Hasher` trait was actually just a factory for various states, but hashing had very little control over how these states were used. Additionally the old `Hasher` trait was actually fairly unrelated to hashing. This commit redesigns the existing `Hasher` trait to match what the notion of a `Hasher` normally implies with the following definition: trait Hasher { type Output; fn reset(&mut self); fn finish(&self) -> Output; } This `Hasher` trait emphasizes that hashing algorithms may produce outputs other than a `u64`, so the output type is made generic. Other than that, however, very little is assumed about a particular hasher. It is left up to implementors to provide specific methods or trait implementations to feed data into a hasher. The corresponding `Hash` trait becomes: trait Hash<H: Hasher> { fn hash(&self, &mut H); } The old default of `SipState` was removed from this trait as it's not something that we're willing to stabilize until the end of time, but the type parameter is always required to implement `Hasher`. Note that the type parameter `H` remains on the trait to enable multidispatch for specialization of hashing for particular hashers. Note that `Writer` is not mentioned in either of `Hash` or `Hasher`, it is simply used as part `derive` and the implementations for all primitive types. With these definitions, the old `Hasher` trait is realized as a new `HashState` trait in the `collections::hash_state` module as an unstable addition for now. The current definition looks like: trait HashState { type Hasher: Hasher; fn hasher(&self) -> Hasher; } The purpose of this trait is to emphasize that the one piece of functionality for implementors is that new instances of `Hasher` can be created. This conceptually represents the two keys from which more instances of a `SipHasher` can be created, and a `HashState` is what's stored in a `HashMap`, not a `Hasher`. Implementors of custom hash algorithms should implement the `Hasher` trait, and only hash algorithms intended for use in hash maps need to implement or worry about the `HashState` trait. The entire module and `HashState` infrastructure remains `#[unstable]` due to it being recently redesigned, but some other stability decision made for the `std::hash` module are: * The `Writer` trait remains `#[experimental]` as it's intended to be replaced with an `io::Writer` (more details soon). * The top-level `hash` function is `#[unstable]` as it is intended to be generic over the hashing algorithm instead of hardwired to `SipHasher` * The inner `sip` module is now private as its one export, `SipHasher` is reexported in the `hash` module. And finally, a few changes were made to the default parameters on `HashMap`. * The `RandomSipHasher` default type parameter was renamed to `RandomState`. This renaming emphasizes that it is not a hasher, but rather just state to generate hashers. It also moves away from the name "sip" as it may not always be implemented as `SipHasher`. This type lives in the `std::collections::hash_map` module as `#[unstable]` * The associated `Hasher` type of `RandomState` is creatively called... `Hasher`! This concrete structure lives next to `RandomState` as an implemenation of the "default hashing algorithm" used for a `HashMap`. Under the hood this is currently implemented as `SipHasher`, but it draws an explicit interface for now and allows us to modify the implementation over time if necessary. There are many breaking changes outlined above, and as a result this commit is a: [breaking-change]
1132 lines
30 KiB
Rust
1132 lines
30 KiB
Rust
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
|
// file at the top-level directory of this distribution and at
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
// option. This file may not be copied, modified, or distributed
|
|
// except according to those terms.
|
|
|
|
//! A simple map based on a vector for small integer keys. Space requirements
|
|
//! are O(highest integer key).
|
|
|
|
#![allow(missing_docs)]
|
|
|
|
use core::prelude::*;
|
|
|
|
use core::cmp::Ordering;
|
|
use core::default::Default;
|
|
use core::fmt;
|
|
use core::hash::{Hash, Writer, Hasher};
|
|
use core::iter::{Enumerate, FilterMap, Map, FromIterator};
|
|
use core::iter;
|
|
use core::mem::replace;
|
|
use core::ops::{Index, IndexMut};
|
|
|
|
use {vec, slice};
|
|
use vec::Vec;
|
|
|
|
// FIXME(conventions): capacity management???
|
|
|
|
/// A map optimized for small integer keys.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// 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.get(&1), Some(&"Jan"));
|
|
///
|
|
/// match months.get_mut(&3) {
|
|
/// Some(value) => *value = "Venus",
|
|
/// None => (),
|
|
/// }
|
|
///
|
|
/// assert_eq!(months.get(&3), Some(&"Venus"));
|
|
///
|
|
/// // Print out all months
|
|
/// for (key, value) in months.iter() {
|
|
/// println!("month {} is {}", key, value);
|
|
/// }
|
|
///
|
|
/// months.clear();
|
|
/// assert!(months.is_empty());
|
|
/// ```
|
|
pub struct VecMap<V> {
|
|
v: Vec<Option<V>>,
|
|
}
|
|
|
|
#[stable]
|
|
impl<V> Default for VecMap<V> {
|
|
#[stable]
|
|
#[inline]
|
|
fn default() -> VecMap<V> { VecMap::new() }
|
|
}
|
|
|
|
impl<V:Clone> Clone for VecMap<V> {
|
|
#[inline]
|
|
fn clone(&self) -> VecMap<V> {
|
|
VecMap { v: self.v.clone() }
|
|
}
|
|
|
|
#[inline]
|
|
fn clone_from(&mut self, source: &VecMap<V>) {
|
|
self.v.clone_from(&source.v);
|
|
}
|
|
}
|
|
|
|
impl<S: Writer + Hasher, V: Hash<S>> Hash<S> for VecMap<V> {
|
|
fn hash(&self, state: &mut S) {
|
|
// In order to not traverse the `VecMap` twice, count the elements
|
|
// during iteration.
|
|
let mut count: uint = 0;
|
|
for elt in self.iter() {
|
|
elt.hash(state);
|
|
count += 1;
|
|
}
|
|
count.hash(state);
|
|
}
|
|
}
|
|
|
|
impl<V> VecMap<V> {
|
|
/// Creates an empty `VecMap`.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// use std::collections::VecMap;
|
|
/// let mut map: VecMap<&str> = VecMap::new();
|
|
/// ```
|
|
#[stable]
|
|
pub fn new() -> VecMap<V> { VecMap { v: vec![] } }
|
|
|
|
/// Creates an empty `VecMap` with space for at least `capacity`
|
|
/// elements before resizing.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// use std::collections::VecMap;
|
|
/// let mut map: VecMap<&str> = VecMap::with_capacity(10);
|
|
/// ```
|
|
#[stable]
|
|
pub fn with_capacity(capacity: uint) -> VecMap<V> {
|
|
VecMap { v: Vec::with_capacity(capacity) }
|
|
}
|
|
|
|
/// Returns the number of elements the `VecMap` can hold without
|
|
/// reallocating.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// use std::collections::VecMap;
|
|
/// let map: VecMap<String> = VecMap::with_capacity(10);
|
|
/// assert!(map.capacity() >= 10);
|
|
/// ```
|
|
#[inline]
|
|
#[stable]
|
|
pub fn capacity(&self) -> uint {
|
|
self.v.capacity()
|
|
}
|
|
|
|
/// Reserves capacity for the given `VecMap` to contain `len` distinct keys.
|
|
/// In the case of `VecMap` this means reallocations will not occur as long
|
|
/// as all inserted keys are less than `len`.
|
|
///
|
|
/// The collection may reserve more space to avoid frequent reallocations.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// use std::collections::VecMap;
|
|
/// let mut map: VecMap<&str> = VecMap::new();
|
|
/// map.reserve_len(10);
|
|
/// assert!(map.capacity() >= 10);
|
|
/// ```
|
|
#[stable]
|
|
pub fn reserve_len(&mut self, len: uint) {
|
|
let cur_len = self.v.len();
|
|
if len >= cur_len {
|
|
self.v.reserve(len - cur_len);
|
|
}
|
|
}
|
|
|
|
/// Reserves the minimum capacity for the given `VecMap` to contain `len` distinct keys.
|
|
/// In the case of `VecMap` this means reallocations will not occur as long as all inserted
|
|
/// keys are less than `len`.
|
|
///
|
|
/// Note that the allocator may give the collection more space than it requests.
|
|
/// Therefore capacity cannot be relied upon to be precisely minimal. Prefer
|
|
/// `reserve_len` if future insertions are expected.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// use std::collections::VecMap;
|
|
/// let mut map: VecMap<&str> = VecMap::new();
|
|
/// map.reserve_len_exact(10);
|
|
/// assert!(map.capacity() >= 10);
|
|
/// ```
|
|
#[stable]
|
|
pub fn reserve_len_exact(&mut self, len: uint) {
|
|
let cur_len = self.v.len();
|
|
if len >= cur_len {
|
|
self.v.reserve_exact(len - cur_len);
|
|
}
|
|
}
|
|
|
|
/// Returns an iterator visiting all keys in ascending order by the keys.
|
|
/// The iterator's element type is `uint`.
|
|
#[stable]
|
|
pub fn keys<'r>(&'r self) -> Keys<'r, V> {
|
|
fn first<A, B>((a, _): (A, B)) -> A { a }
|
|
let first: fn((uint, &'r V)) -> uint = first; // coerce to fn pointer
|
|
|
|
Keys { iter: self.iter().map(first) }
|
|
}
|
|
|
|
/// Returns an iterator visiting all values in ascending order by the keys.
|
|
/// The iterator's element type is `&'r V`.
|
|
#[stable]
|
|
pub fn values<'r>(&'r self) -> Values<'r, V> {
|
|
fn second<A, B>((_, b): (A, B)) -> B { b }
|
|
let second: fn((uint, &'r V)) -> &'r V = second; // coerce to fn pointer
|
|
|
|
Values { iter: self.iter().map(second) }
|
|
}
|
|
|
|
/// Returns an iterator visiting all key-value pairs in ascending order by the keys.
|
|
/// The iterator's element type is `(uint, &'r V)`.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// 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);
|
|
/// }
|
|
/// ```
|
|
#[stable]
|
|
pub fn iter<'r>(&'r self) -> Iter<'r, V> {
|
|
Iter {
|
|
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)`.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// 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");
|
|
/// }
|
|
/// ```
|
|
#[stable]
|
|
pub fn iter_mut<'r>(&'r mut self) -> IterMut<'r, V> {
|
|
IterMut {
|
|
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)`.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// 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")]);
|
|
/// ```
|
|
#[stable]
|
|
pub fn into_iter(&mut self) -> IntoIter<V> {
|
|
fn filter<A>((i, v): (uint, Option<A>)) -> Option<(uint, A)> {
|
|
v.map(|v| (i, v))
|
|
}
|
|
let filter: fn((uint, Option<V>)) -> Option<(uint, V)> = filter; // coerce to fn ptr
|
|
|
|
let values = replace(&mut self.v, vec!());
|
|
IntoIter { iter: values.into_iter().enumerate().filter_map(filter) }
|
|
}
|
|
|
|
/// Return the number of elements in the map.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// use std::collections::VecMap;
|
|
///
|
|
/// let mut a = VecMap::new();
|
|
/// assert_eq!(a.len(), 0);
|
|
/// a.insert(1, "a");
|
|
/// assert_eq!(a.len(), 1);
|
|
/// ```
|
|
#[stable]
|
|
pub fn len(&self) -> uint {
|
|
self.v.iter().filter(|elt| elt.is_some()).count()
|
|
}
|
|
|
|
/// Return true if the map contains no elements.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// use std::collections::VecMap;
|
|
///
|
|
/// let mut a = VecMap::new();
|
|
/// assert!(a.is_empty());
|
|
/// a.insert(1, "a");
|
|
/// assert!(!a.is_empty());
|
|
/// ```
|
|
#[stable]
|
|
pub fn is_empty(&self) -> bool {
|
|
self.v.iter().all(|elt| elt.is_none())
|
|
}
|
|
|
|
/// Clears the map, removing all key-value pairs.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// use std::collections::VecMap;
|
|
///
|
|
/// let mut a = VecMap::new();
|
|
/// a.insert(1, "a");
|
|
/// a.clear();
|
|
/// assert!(a.is_empty());
|
|
/// ```
|
|
#[stable]
|
|
pub fn clear(&mut self) { self.v.clear() }
|
|
|
|
/// Returns a reference to the value corresponding to the key.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// use std::collections::VecMap;
|
|
///
|
|
/// let mut map = VecMap::new();
|
|
/// map.insert(1, "a");
|
|
/// assert_eq!(map.get(&1), Some(&"a"));
|
|
/// assert_eq!(map.get(&2), None);
|
|
/// ```
|
|
#[stable]
|
|
pub fn get(&self, key: &uint) -> Option<&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.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// 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]
|
|
#[stable]
|
|
pub fn contains_key(&self, key: &uint) -> bool {
|
|
self.get(key).is_some()
|
|
}
|
|
|
|
/// Returns a mutable reference to the value corresponding to the key.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// use std::collections::VecMap;
|
|
///
|
|
/// let mut map = VecMap::new();
|
|
/// map.insert(1, "a");
|
|
/// match map.get_mut(&1) {
|
|
/// Some(x) => *x = "b",
|
|
/// None => (),
|
|
/// }
|
|
/// assert_eq!(map[1], "b");
|
|
/// ```
|
|
#[stable]
|
|
pub fn get_mut(&mut self, key: &uint) -> Option<&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 from the map. If the key already had a value
|
|
/// present in the map, that value is returned. Otherwise, `None` is returned.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// use std::collections::VecMap;
|
|
///
|
|
/// let mut map = VecMap::new();
|
|
/// assert_eq!(map.insert(37, "a"), None);
|
|
/// assert_eq!(map.is_empty(), false);
|
|
///
|
|
/// map.insert(37, "b");
|
|
/// assert_eq!(map.insert(37, "c"), Some("b"));
|
|
/// assert_eq!(map[37], "c");
|
|
/// ```
|
|
#[stable]
|
|
pub fn insert(&mut self, key: uint, value: V) -> Option<V> {
|
|
let len = self.v.len();
|
|
if len <= key {
|
|
self.v.extend(range(0, key - len + 1).map(|_| None));
|
|
}
|
|
replace(&mut self.v[key], Some(value))
|
|
}
|
|
|
|
/// Removes a key from the map, returning the value at the key if the key
|
|
/// was previously in the map.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// use std::collections::VecMap;
|
|
///
|
|
/// let mut map = VecMap::new();
|
|
/// map.insert(1, "a");
|
|
/// assert_eq!(map.remove(&1), Some("a"));
|
|
/// assert_eq!(map.remove(&1), None);
|
|
/// ```
|
|
#[stable]
|
|
pub fn remove(&mut self, key: &uint) -> Option<V> {
|
|
if *key >= self.v.len() {
|
|
return None;
|
|
}
|
|
let result = &mut self.v[*key];
|
|
result.take()
|
|
}
|
|
}
|
|
|
|
#[stable]
|
|
impl<V: PartialEq> PartialEq for VecMap<V> {
|
|
fn eq(&self, other: &VecMap<V>) -> bool {
|
|
iter::order::eq(self.iter(), other.iter())
|
|
}
|
|
}
|
|
|
|
#[stable]
|
|
impl<V: Eq> Eq for VecMap<V> {}
|
|
|
|
#[stable]
|
|
impl<V: PartialOrd> PartialOrd for VecMap<V> {
|
|
#[inline]
|
|
fn partial_cmp(&self, other: &VecMap<V>) -> Option<Ordering> {
|
|
iter::order::partial_cmp(self.iter(), other.iter())
|
|
}
|
|
}
|
|
|
|
#[stable]
|
|
impl<V: Ord> Ord for VecMap<V> {
|
|
#[inline]
|
|
fn cmp(&self, other: &VecMap<V>) -> Ordering {
|
|
iter::order::cmp(self.iter(), other.iter())
|
|
}
|
|
}
|
|
|
|
#[stable]
|
|
impl<V: fmt::Show> fmt::Show for VecMap<V> {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
try!(write!(f, "VecMap {{"));
|
|
|
|
for (i, (k, v)) in self.iter().enumerate() {
|
|
if i != 0 { try!(write!(f, ", ")); }
|
|
try!(write!(f, "{}: {:?}", k, *v));
|
|
}
|
|
|
|
write!(f, "}}")
|
|
}
|
|
}
|
|
|
|
#[stable]
|
|
impl<V> FromIterator<(uint, V)> for VecMap<V> {
|
|
fn from_iter<Iter: Iterator<Item=(uint, V)>>(iter: Iter) -> VecMap<V> {
|
|
let mut map = VecMap::new();
|
|
map.extend(iter);
|
|
map
|
|
}
|
|
}
|
|
|
|
#[stable]
|
|
impl<V> Extend<(uint, V)> for VecMap<V> {
|
|
fn extend<Iter: Iterator<Item=(uint, V)>>(&mut self, mut iter: Iter) {
|
|
for (k, v) in iter {
|
|
self.insert(k, v);
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<V> Index<uint> for VecMap<V> {
|
|
type Output = V;
|
|
|
|
#[inline]
|
|
fn index<'a>(&'a self, i: &uint) -> &'a V {
|
|
self.get(i).expect("key not present")
|
|
}
|
|
}
|
|
|
|
#[stable]
|
|
impl<V> IndexMut<uint> for VecMap<V> {
|
|
type Output = V;
|
|
|
|
#[inline]
|
|
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut V {
|
|
self.get_mut(i).expect("key not present")
|
|
}
|
|
}
|
|
|
|
macro_rules! iterator {
|
|
(impl $name:ident -> $elem:ty, $($getter:ident),+) => {
|
|
#[stable]
|
|
impl<'a, V> Iterator for $name<'a, V> {
|
|
type Item = $elem;
|
|
|
|
#[inline]
|
|
fn next(&mut self) -> Option<$elem> {
|
|
while self.front < self.back {
|
|
match self.iter.next() {
|
|
Some(elem) => {
|
|
match elem$(. $getter ())+ {
|
|
Some(x) => {
|
|
let index = self.front;
|
|
self.front += 1;
|
|
return Some((index, x));
|
|
},
|
|
None => {},
|
|
}
|
|
}
|
|
_ => ()
|
|
}
|
|
self.front += 1;
|
|
}
|
|
None
|
|
}
|
|
|
|
#[inline]
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
(0, Some(self.back - self.front))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
macro_rules! double_ended_iterator {
|
|
(impl $name:ident -> $elem:ty, $($getter:ident),+) => {
|
|
#[stable]
|
|
impl<'a, V> DoubleEndedIterator for $name<'a, V> {
|
|
#[inline]
|
|
fn next_back(&mut self) -> Option<$elem> {
|
|
while self.front < self.back {
|
|
match self.iter.next_back() {
|
|
Some(elem) => {
|
|
match elem$(. $getter ())+ {
|
|
Some(x) => {
|
|
self.back -= 1;
|
|
return Some((self.back, x));
|
|
},
|
|
None => {},
|
|
}
|
|
}
|
|
_ => ()
|
|
}
|
|
self.back -= 1;
|
|
}
|
|
None
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// An iterator over the key-value pairs of a map.
|
|
#[stable]
|
|
pub struct Iter<'a, V:'a> {
|
|
front: uint,
|
|
back: uint,
|
|
iter: slice::Iter<'a, Option<V>>
|
|
}
|
|
|
|
// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
|
|
impl<'a, V> Clone for Iter<'a, V> {
|
|
fn clone(&self) -> Iter<'a, V> {
|
|
Iter {
|
|
front: self.front,
|
|
back: self.back,
|
|
iter: self.iter.clone()
|
|
}
|
|
}
|
|
}
|
|
|
|
iterator! { impl Iter -> (uint, &'a V), as_ref }
|
|
double_ended_iterator! { impl Iter -> (uint, &'a V), as_ref }
|
|
|
|
/// An iterator over the key-value pairs of a map, with the
|
|
/// values being mutable.
|
|
#[stable]
|
|
pub struct IterMut<'a, V:'a> {
|
|
front: uint,
|
|
back: uint,
|
|
iter: slice::IterMut<'a, Option<V>>
|
|
}
|
|
|
|
iterator! { impl IterMut -> (uint, &'a mut V), as_mut }
|
|
double_ended_iterator! { impl IterMut -> (uint, &'a mut V), as_mut }
|
|
|
|
/// An iterator over the keys of a map.
|
|
#[stable]
|
|
pub struct Keys<'a, V: 'a> {
|
|
iter: Map<(uint, &'a V), uint, Iter<'a, V>, fn((uint, &'a V)) -> uint>
|
|
}
|
|
|
|
// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
|
|
impl<'a, V> Clone for Keys<'a, V> {
|
|
fn clone(&self) -> Keys<'a, V> {
|
|
Keys {
|
|
iter: self.iter.clone()
|
|
}
|
|
}
|
|
}
|
|
|
|
/// An iterator over the values of a map.
|
|
#[stable]
|
|
pub struct Values<'a, V: 'a> {
|
|
iter: Map<(uint, &'a V), &'a V, Iter<'a, V>, fn((uint, &'a V)) -> &'a V>
|
|
}
|
|
|
|
// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
|
|
impl<'a, V> Clone for Values<'a, V> {
|
|
fn clone(&self) -> Values<'a, V> {
|
|
Values {
|
|
iter: self.iter.clone()
|
|
}
|
|
}
|
|
}
|
|
|
|
/// A consuming iterator over the key-value pairs of a map.
|
|
#[stable]
|
|
pub struct IntoIter<V> {
|
|
iter: FilterMap<
|
|
(uint, Option<V>),
|
|
(uint, V),
|
|
Enumerate<vec::IntoIter<Option<V>>>,
|
|
fn((uint, Option<V>)) -> Option<(uint, V)>>
|
|
}
|
|
|
|
#[stable]
|
|
impl<'a, V> Iterator for Keys<'a, V> {
|
|
type Item = uint;
|
|
|
|
fn next(&mut self) -> Option<uint> { self.iter.next() }
|
|
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
|
|
}
|
|
#[stable]
|
|
impl<'a, V> DoubleEndedIterator for Keys<'a, V> {
|
|
fn next_back(&mut self) -> Option<uint> { self.iter.next_back() }
|
|
}
|
|
|
|
#[stable]
|
|
impl<'a, V> Iterator for Values<'a, V> {
|
|
type Item = &'a V;
|
|
|
|
fn next(&mut self) -> Option<(&'a V)> { self.iter.next() }
|
|
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
|
|
}
|
|
#[stable]
|
|
impl<'a, V> DoubleEndedIterator for Values<'a, V> {
|
|
fn next_back(&mut self) -> Option<(&'a V)> { self.iter.next_back() }
|
|
}
|
|
|
|
#[stable]
|
|
impl<V> Iterator for IntoIter<V> {
|
|
type Item = (uint, V);
|
|
|
|
fn next(&mut self) -> Option<(uint, V)> { self.iter.next() }
|
|
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
|
|
}
|
|
#[stable]
|
|
impl<V> DoubleEndedIterator for IntoIter<V> {
|
|
fn next_back(&mut self) -> Option<(uint, V)> { self.iter.next_back() }
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test_map {
|
|
use prelude::*;
|
|
use core::hash::{hash, SipHasher};
|
|
|
|
use super::VecMap;
|
|
|
|
#[test]
|
|
fn test_get_mut() {
|
|
let mut m = VecMap::new();
|
|
assert!(m.insert(1, 12i).is_none());
|
|
assert!(m.insert(2, 8).is_none());
|
|
assert!(m.insert(5, 14).is_none());
|
|
let new = 100;
|
|
match m.get_mut(&5) {
|
|
None => panic!(), Some(x) => *x = new
|
|
}
|
|
assert_eq!(m.get(&5), Some(&new));
|
|
}
|
|
|
|
#[test]
|
|
fn test_len() {
|
|
let mut map = VecMap::new();
|
|
assert_eq!(map.len(), 0);
|
|
assert!(map.is_empty());
|
|
assert!(map.insert(5, 20i).is_none());
|
|
assert_eq!(map.len(), 1);
|
|
assert!(!map.is_empty());
|
|
assert!(map.insert(11, 12).is_none());
|
|
assert_eq!(map.len(), 2);
|
|
assert!(!map.is_empty());
|
|
assert!(map.insert(14, 22).is_none());
|
|
assert_eq!(map.len(), 3);
|
|
assert!(!map.is_empty());
|
|
}
|
|
|
|
#[test]
|
|
fn test_clear() {
|
|
let mut map = VecMap::new();
|
|
assert!(map.insert(5, 20i).is_none());
|
|
assert!(map.insert(11, 12).is_none());
|
|
assert!(map.insert(14, 22).is_none());
|
|
map.clear();
|
|
assert!(map.is_empty());
|
|
assert!(map.get(&5).is_none());
|
|
assert!(map.get(&11).is_none());
|
|
assert!(map.get(&14).is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn test_insert() {
|
|
let mut m = VecMap::new();
|
|
assert_eq!(m.insert(1, 2i), None);
|
|
assert_eq!(m.insert(1, 3i), Some(2));
|
|
assert_eq!(m.insert(1, 4i), Some(3));
|
|
}
|
|
|
|
#[test]
|
|
fn test_remove() {
|
|
let mut m = VecMap::new();
|
|
m.insert(1, 2i);
|
|
assert_eq!(m.remove(&1), Some(2));
|
|
assert_eq!(m.remove(&1), None);
|
|
}
|
|
|
|
#[test]
|
|
fn test_keys() {
|
|
let mut map = VecMap::new();
|
|
map.insert(1, 'a');
|
|
map.insert(2, 'b');
|
|
map.insert(3, 'c');
|
|
let keys = map.keys().collect::<Vec<uint>>();
|
|
assert_eq!(keys.len(), 3);
|
|
assert!(keys.contains(&1));
|
|
assert!(keys.contains(&2));
|
|
assert!(keys.contains(&3));
|
|
}
|
|
|
|
#[test]
|
|
fn test_values() {
|
|
let mut map = VecMap::new();
|
|
map.insert(1, 'a');
|
|
map.insert(2, 'b');
|
|
map.insert(3, 'c');
|
|
let values = map.values().map(|&v| v).collect::<Vec<char>>();
|
|
assert_eq!(values.len(), 3);
|
|
assert!(values.contains(&'a'));
|
|
assert!(values.contains(&'b'));
|
|
assert!(values.contains(&'c'));
|
|
}
|
|
|
|
#[test]
|
|
fn test_iterator() {
|
|
let mut m = VecMap::new();
|
|
|
|
assert!(m.insert(0, 1i).is_none());
|
|
assert!(m.insert(1, 2).is_none());
|
|
assert!(m.insert(3, 5).is_none());
|
|
assert!(m.insert(6, 10).is_none());
|
|
assert!(m.insert(10, 11).is_none());
|
|
|
|
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).is_none());
|
|
assert!(m.insert(1, 2).is_none());
|
|
assert!(m.insert(3, 5).is_none());
|
|
assert!(m.insert(6, 10).is_none());
|
|
assert!(m.insert(10, 11).is_none());
|
|
|
|
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).is_none());
|
|
assert!(m.insert(1, 2).is_none());
|
|
assert!(m.insert(3, 5).is_none());
|
|
assert!(m.insert(6, 10).is_none());
|
|
assert!(m.insert(10, 11).is_none());
|
|
|
|
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).is_none());
|
|
assert!(m.insert(1, 2).is_none());
|
|
assert!(m.insert(3, 5).is_none());
|
|
assert!(m.insert(6, 10).is_none());
|
|
assert!(m.insert(10, 11).is_none());
|
|
|
|
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).is_none());
|
|
assert!(m.insert(1, 2).is_none());
|
|
assert!(m.insert(3, 5).is_none());
|
|
assert!(m.insert(6, 10).is_none());
|
|
assert!(m.insert(10, 11).is_none());
|
|
|
|
for (k, v) in m.iter_mut().rev() {
|
|
*v += k as int;
|
|
}
|
|
|
|
let mut it = m.iter();
|
|
assert_eq!(it.next().unwrap(), (0, &1));
|
|
assert_eq!(it.next().unwrap(), (1, &3));
|
|
assert_eq!(it.next().unwrap(), (3, &8));
|
|
assert_eq!(it.next().unwrap(), (6, &16));
|
|
assert_eq!(it.next().unwrap(), (10, &21));
|
|
assert!(it.next().is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn test_move_iter() {
|
|
let mut m = VecMap::new();
|
|
m.insert(1, box 2i);
|
|
let mut called = false;
|
|
for (k, v) in m.into_iter() {
|
|
assert!(!called);
|
|
called = true;
|
|
assert_eq!(k, 1);
|
|
assert_eq!(v, box 2i);
|
|
}
|
|
assert!(called);
|
|
m.insert(2, box 1i);
|
|
}
|
|
|
|
#[test]
|
|
fn test_show() {
|
|
let mut map = VecMap::new();
|
|
let empty = VecMap::<int>::new();
|
|
|
|
map.insert(1, 2i);
|
|
map.insert(3, 4i);
|
|
|
|
let map_str = format!("{:?}", map);
|
|
assert!(map_str == "VecMap {1: 2i, 3: 4i}" || map_str == "{3: 4i, 1: 2i}");
|
|
assert_eq!(format!("{:?}", empty), "VecMap {}");
|
|
}
|
|
|
|
#[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).is_none());
|
|
assert!(a != b);
|
|
assert!(b.insert(0, 4i).is_none());
|
|
assert!(a != b);
|
|
assert!(a.insert(5, 19).is_none());
|
|
assert!(a != b);
|
|
assert!(!b.insert(0, 5).is_none());
|
|
assert!(a != b);
|
|
assert!(b.insert(5, 19).is_none());
|
|
assert!(a == b);
|
|
|
|
a = VecMap::new();
|
|
b = VecMap::with_capacity(1);
|
|
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).is_none());
|
|
assert!(a < b);
|
|
assert!(a.insert(2, 7).is_none());
|
|
assert!(!(a < b) && b < a);
|
|
assert!(b.insert(1, 0).is_none());
|
|
assert!(b < a);
|
|
assert!(a.insert(0, 6).is_none());
|
|
assert!(a < b);
|
|
assert!(a.insert(6, 2).is_none());
|
|
assert!(a < b && !(b < a));
|
|
}
|
|
|
|
#[test]
|
|
fn test_ord() {
|
|
let mut a = VecMap::new();
|
|
let mut b = VecMap::new();
|
|
|
|
assert!(a <= b && a >= b);
|
|
assert!(a.insert(1u, 1i).is_none());
|
|
assert!(a > b && a >= b);
|
|
assert!(b < a && b <= a);
|
|
assert!(b.insert(2, 2).is_none());
|
|
assert!(b > a && b >= a);
|
|
assert!(a < b && a <= b);
|
|
}
|
|
|
|
#[test]
|
|
fn test_hash() {
|
|
let mut x = VecMap::new();
|
|
let mut y = VecMap::new();
|
|
|
|
assert!(hash::<_, SipHasher>(&x) == hash::<_, SipHasher>(&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::<_, SipHasher>(&x) == hash::<_, SipHasher>(&y));
|
|
|
|
x.insert(1000, 'd');
|
|
x.remove(&1000);
|
|
|
|
assert!(hash::<_, SipHasher>(&x) == hash::<_, SipHasher>(&y));
|
|
}
|
|
|
|
#[test]
|
|
fn test_from_iter() {
|
|
let xs: Vec<(uint, char)> = vec![(1u, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')];
|
|
|
|
let map: VecMap<char> = xs.iter().map(|&x| x).collect();
|
|
|
|
for &(k, v) in xs.iter() {
|
|
assert_eq!(map.get(&k), Some(&v));
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_index() {
|
|
let mut map: VecMap<int> = VecMap::new();
|
|
|
|
map.insert(1, 2);
|
|
map.insert(2, 1);
|
|
map.insert(3, 4);
|
|
|
|
assert_eq!(map[3], 4);
|
|
}
|
|
|
|
#[test]
|
|
#[should_fail]
|
|
fn test_index_nonexistent() {
|
|
let mut map: VecMap<int> = VecMap::new();
|
|
|
|
map.insert(1, 2);
|
|
map.insert(2, 1);
|
|
map.insert(3, 4);
|
|
|
|
map[4];
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod bench {
|
|
use test::Bencher;
|
|
use super::VecMap;
|
|
use bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n};
|
|
|
|
#[bench]
|
|
pub fn insert_rand_100(b: &mut Bencher) {
|
|
let mut m : VecMap<uint> = VecMap::new();
|
|
insert_rand_n(100, &mut m, b,
|
|
|m, i| { m.insert(i, 1); },
|
|
|m, i| { m.remove(&i); });
|
|
}
|
|
|
|
#[bench]
|
|
pub fn insert_rand_10_000(b: &mut Bencher) {
|
|
let mut m : VecMap<uint> = VecMap::new();
|
|
insert_rand_n(10_000, &mut m, b,
|
|
|m, i| { m.insert(i, 1); },
|
|
|m, i| { m.remove(&i); });
|
|
}
|
|
|
|
// Insert seq
|
|
#[bench]
|
|
pub fn insert_seq_100(b: &mut Bencher) {
|
|
let mut m : VecMap<uint> = VecMap::new();
|
|
insert_seq_n(100, &mut m, b,
|
|
|m, i| { m.insert(i, 1); },
|
|
|m, i| { m.remove(&i); });
|
|
}
|
|
|
|
#[bench]
|
|
pub fn insert_seq_10_000(b: &mut Bencher) {
|
|
let mut m : VecMap<uint> = VecMap::new();
|
|
insert_seq_n(10_000, &mut m, b,
|
|
|m, i| { m.insert(i, 1); },
|
|
|m, i| { m.remove(&i); });
|
|
}
|
|
|
|
// Find rand
|
|
#[bench]
|
|
pub fn find_rand_100(b: &mut Bencher) {
|
|
let mut m : VecMap<uint> = VecMap::new();
|
|
find_rand_n(100, &mut m, b,
|
|
|m, i| { m.insert(i, 1); },
|
|
|m, i| { m.get(&i); });
|
|
}
|
|
|
|
#[bench]
|
|
pub fn find_rand_10_000(b: &mut Bencher) {
|
|
let mut m : VecMap<uint> = VecMap::new();
|
|
find_rand_n(10_000, &mut m, b,
|
|
|m, i| { m.insert(i, 1); },
|
|
|m, i| { m.get(&i); });
|
|
}
|
|
|
|
// Find seq
|
|
#[bench]
|
|
pub fn find_seq_100(b: &mut Bencher) {
|
|
let mut m : VecMap<uint> = VecMap::new();
|
|
find_seq_n(100, &mut m, b,
|
|
|m, i| { m.insert(i, 1); },
|
|
|m, i| { m.get(&i); });
|
|
}
|
|
|
|
#[bench]
|
|
pub fn find_seq_10_000(b: &mut Bencher) {
|
|
let mut m : VecMap<uint> = VecMap::new();
|
|
find_seq_n(10_000, &mut m, b,
|
|
|m, i| { m.insert(i, 1); },
|
|
|m, i| { m.get(&i); });
|
|
}
|
|
}
|