rust/src/libcollections/vec_map.rs

1054 lines
30 KiB
Rust
Raw Normal View History

Deprecate the rev_iter pattern in all places where a DoubleEndedIterator is provided (everywhere but treemap) This commit deprecates rev_iter, mut_rev_iter, move_rev_iter everywhere (except treemap) and also deprecates related functions like rsplit, rev_components, and rev_str_components. In every case, these functions can be replaced with the non-reversed form followed by a call to .rev(). To make this more concrete, a translation table for all functional changes necessary follows: * container.rev_iter() -> container.iter().rev() * container.mut_rev_iter() -> container.mut_iter().rev() * container.move_rev_iter() -> container.move_iter().rev() * sliceorstr.rsplit(sep) -> sliceorstr.split(sep).rev() * path.rev_components() -> path.components().rev() * path.rev_str_components() -> path.str_components().rev() In terms of the type system, this change also deprecates any specialized reversed iterator types (except in treemap), opting instead to use Rev directly if any type annotations are needed. However, since methods directly returning reversed iterators are now discouraged, the need for such annotations should be small. However, in those cases, the general pattern for conversion is to take whatever follows Rev in the original reversed name and surround it with Rev<>: * RevComponents<'a> -> Rev<Components<'a>> * RevStrComponents<'a> -> Rev<StrComponents<'a>> * RevItems<'a, T> -> Rev<Items<'a, T>> * etc. The reasoning behind this change is that it makes the standard API much simpler without reducing readability, performance, or power. The presence of functions such as rev_iter adds more boilerplate code to libraries (all of which simply call .iter().rev()), clutters up the documentation, and only helps code by saving two characters. Additionally, the numerous type synonyms that were used to make the type signatures look nice like RevItems add even more boilerplate and clutter up the docs even more. With this change, all that cruft goes away. [breaking-change]
2014-04-20 23:59:12 -05:00
// 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.
2014-07-24 15:22:24 +02:00
//! A simple map based on a vector for small integer keys. Space requirements
//! are O(highest integer key).
2014-10-27 15:37:07 -07:00
#![allow(missing_docs)]
2015-02-04 19:36:02 -05:00
use self::Entry::*;
2015-02-03 00:47:38 -05:00
std: Recreate a `collections` module As with the previous commit with `librand`, this commit shuffles around some `collections` code. The new state of the world is similar to that of librand: * The libcollections crate now only depends on libcore and liballoc. * The standard library has a new module, `std::collections`. All functionality of libcollections is reexported through this module. I would like to stress that this change is purely cosmetic. There are very few alterations to these primitives. There are a number of notable points about the new organization: * std::{str, slice, string, vec} all moved to libcollections. There is no reason that these primitives shouldn't be necessarily usable in a freestanding context that has allocation. These are all reexported in their usual places in the standard library. * The `hashmap`, and transitively the `lru_cache`, modules no longer reside in `libcollections`, but rather in libstd. The reason for this is because the `HashMap::new` contructor requires access to the OSRng for initially seeding the hash map. Beyond this requirement, there is no reason that the hashmap could not move to libcollections. I do, however, have a plan to move the hash map to the collections module. The `HashMap::new` function could be altered to require that the `H` hasher parameter ascribe to the `Default` trait, allowing the entire `hashmap` module to live in libcollections. The key idea would be that the default hasher would be different in libstd. Something along the lines of: // src/libstd/collections/mod.rs pub type HashMap<K, V, H = RandomizedSipHasher> = core_collections::HashMap<K, V, H>; This is not possible today because you cannot invoke static methods through type aliases. If we modified the compiler, however, to allow invocation of static methods through type aliases, then this type definition would essentially be switching the default hasher from `SipHasher` in libcollections to a libstd-defined `RandomizedSipHasher` type. This type's `Default` implementation would randomly seed the `SipHasher` instance, and otherwise perform the same as `SipHasher`. This future state doesn't seem incredibly far off, but until that time comes, the hashmap module will live in libstd to not compromise on functionality. * In preparation for the hashmap moving to libcollections, the `hash` module has moved from libstd to libcollections. A previously snapshotted commit enables a distinct `Writer` trait to live in the `hash` module which `Hash` implementations are now parameterized over. Due to using a custom trait, the `SipHasher` implementation has lost its specialized methods for writing integers. These can be re-added backwards-compatibly in the future via default methods if necessary, but the FNV hashing should satisfy much of the need for speedier hashing. A list of breaking changes: * HashMap::{get, get_mut} no longer fails with the key formatted into the error message with `{:?}`, instead, a generic message is printed. With backtraces, it should still be not-too-hard to track down errors. * The HashMap, HashSet, and LruCache types are now available through std::collections instead of the collections crate. * Manual implementations of hash should be parameterized over `hash::Writer` instead of just `Writer`. [breaking-change]
2014-05-29 18:50:12 -07:00
use core::prelude::*;
use core::cmp::{max, Ordering};
2014-06-07 18:17:58 +02:00
use core::fmt;
use core::hash::{Hash, Hasher};
use core::iter::{Enumerate, FilterMap, Map, FromIterator};
use core::iter;
use core::mem::{replace, swap};
use core::ops::{Index, IndexMut};
std: Recreate a `collections` module As with the previous commit with `librand`, this commit shuffles around some `collections` code. The new state of the world is similar to that of librand: * The libcollections crate now only depends on libcore and liballoc. * The standard library has a new module, `std::collections`. All functionality of libcollections is reexported through this module. I would like to stress that this change is purely cosmetic. There are very few alterations to these primitives. There are a number of notable points about the new organization: * std::{str, slice, string, vec} all moved to libcollections. There is no reason that these primitives shouldn't be necessarily usable in a freestanding context that has allocation. These are all reexported in their usual places in the standard library. * The `hashmap`, and transitively the `lru_cache`, modules no longer reside in `libcollections`, but rather in libstd. The reason for this is because the `HashMap::new` contructor requires access to the OSRng for initially seeding the hash map. Beyond this requirement, there is no reason that the hashmap could not move to libcollections. I do, however, have a plan to move the hash map to the collections module. The `HashMap::new` function could be altered to require that the `H` hasher parameter ascribe to the `Default` trait, allowing the entire `hashmap` module to live in libcollections. The key idea would be that the default hasher would be different in libstd. Something along the lines of: // src/libstd/collections/mod.rs pub type HashMap<K, V, H = RandomizedSipHasher> = core_collections::HashMap<K, V, H>; This is not possible today because you cannot invoke static methods through type aliases. If we modified the compiler, however, to allow invocation of static methods through type aliases, then this type definition would essentially be switching the default hasher from `SipHasher` in libcollections to a libstd-defined `RandomizedSipHasher` type. This type's `Default` implementation would randomly seed the `SipHasher` instance, and otherwise perform the same as `SipHasher`. This future state doesn't seem incredibly far off, but until that time comes, the hashmap module will live in libstd to not compromise on functionality. * In preparation for the hashmap moving to libcollections, the `hash` module has moved from libstd to libcollections. A previously snapshotted commit enables a distinct `Writer` trait to live in the `hash` module which `Hash` implementations are now parameterized over. Due to using a custom trait, the `SipHasher` implementation has lost its specialized methods for writing integers. These can be re-added backwards-compatibly in the future via default methods if necessary, but the FNV hashing should satisfy much of the need for speedier hashing. A list of breaking changes: * HashMap::{get, get_mut} no longer fails with the key formatted into the error message with `{:?}`, instead, a generic message is printed. With backtraces, it should still be not-too-hard to track down errors. * The HashMap, HashSet, and LruCache types are now available through std::collections instead of the collections crate. * Manual implementations of hash should be parameterized over `hash::Writer` instead of just `Writer`. [breaking-change]
2014-05-29 18:50:12 -07:00
use {vec, slice};
use vec::Vec;
2014-07-24 15:46:55 +02:00
/// A map optimized for small integer keys.
///
/// # Examples
2014-07-24 15:46:55 +02:00
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
/// use std::collections::VecMap;
2014-07-24 15:46:55 +02:00
///
/// let mut months = VecMap::new();
2014-07-24 15:46:55 +02:00
/// 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"));
2014-07-24 15:46:55 +02:00
///
/// if let Some(value) = months.get_mut(&3) {
/// *value = "Venus";
2014-07-24 15:46:55 +02:00
/// }
///
/// assert_eq!(months.get(&3), Some(&"Venus"));
2014-07-24 15:46:55 +02:00
///
/// // 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>>,
}
2015-02-03 00:47:38 -05:00
/// A view into a single entry in a map, which may either be vacant or occupied.
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-03 00:47:38 -05:00
pub enum Entry<'a, V:'a> {
/// A vacant Entry
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-03 00:47:38 -05:00
Vacant(VacantEntry<'a, V>),
2015-02-03 00:47:38 -05:00
/// An occupied Entry
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-03 00:47:38 -05:00
Occupied(OccupiedEntry<'a, V>),
}
/// A vacant Entry.
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-03 00:47:38 -05:00
pub struct VacantEntry<'a, V:'a> {
map: &'a mut VecMap<V>,
index: usize,
}
/// An occupied Entry.
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-03 00:47:38 -05:00
pub struct OccupiedEntry<'a, V:'a> {
map: &'a mut VecMap<V>,
index: usize,
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<V> Default for VecMap<V> {
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
fn default() -> VecMap<V> { VecMap::new() }
}
#[stable(feature = "rust1", since = "1.0.0")]
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);
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<V: Hash> Hash for VecMap<V> {
fn hash<H: Hasher>(&self, state: &mut H) {
// In order to not traverse the `VecMap` twice, count the elements
// during iteration.
let mut count: usize = 0;
for elt in self {
elt.hash(state);
count += 1;
}
count.hash(state);
}
}
impl<V> VecMap<V> {
/// Creates an empty `VecMap`.
2014-07-24 15:46:55 +02:00
///
/// # Examples
2014-07-24 15:46:55 +02:00
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
/// use std::collections::VecMap;
/// let mut map: VecMap<&str> = VecMap::new();
2014-07-24 15:46:55 +02:00
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new() -> VecMap<V> { VecMap { v: vec![] } }
/// Creates an empty `VecMap` with space for at least `capacity`
2014-08-04 22:48:39 +12:00
/// elements before resizing.
2014-07-24 15:46:55 +02:00
///
/// # Examples
2014-07-24 15:46:55 +02:00
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
/// use std::collections::VecMap;
/// let mut map: VecMap<&str> = VecMap::with_capacity(10);
2014-07-24 15:46:55 +02:00
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
pub fn with_capacity(capacity: usize) -> VecMap<V> {
VecMap { v: Vec::with_capacity(capacity) }
}
/// Returns the number of elements the `VecMap` can hold without
/// reallocating.
///
/// # Examples
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
/// use std::collections::VecMap;
/// let map: VecMap<String> = VecMap::with_capacity(10);
/// assert!(map.capacity() >= 10);
/// ```
#[inline]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
pub fn capacity(&self) -> usize {
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
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
/// use std::collections::VecMap;
/// let mut map: VecMap<&str> = VecMap::new();
/// map.reserve_len(10);
/// assert!(map.capacity() >= 10);
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
pub fn reserve_len(&mut self, len: usize) {
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
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
/// use std::collections::VecMap;
/// let mut map: VecMap<&str> = VecMap::new();
/// map.reserve_len_exact(10);
/// assert!(map.capacity() >= 10);
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
pub fn reserve_len_exact(&mut self, len: usize) {
let cur_len = self.v.len();
if len >= cur_len {
self.v.reserve_exact(len - cur_len);
}
}
2015-01-19 11:06:15 +01:00
/// Returns an iterator visiting all keys in ascending order of the keys.
2015-02-04 21:17:19 -05:00
/// The iterator's element type is `usize`.
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn keys<'r>(&'r self) -> Keys<'r, V> {
2014-12-02 14:07:40 -05:00
fn first<A, B>((a, _): (A, B)) -> A { a }
2015-02-04 21:17:19 -05:00
let first: fn((usize, &'r V)) -> usize = first; // coerce to fn pointer
2014-12-02 14:07:40 -05:00
Keys { iter: self.iter().map(first) }
}
2015-01-19 11:06:15 +01:00
/// Returns an iterator visiting all values in ascending order of the keys.
2014-08-04 22:48:39 +12:00
/// The iterator's element type is `&'r V`.
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn values<'r>(&'r self) -> Values<'r, V> {
2014-12-02 14:07:40 -05:00
fn second<A, B>((_, b): (A, B)) -> B { b }
2015-02-04 21:17:19 -05:00
let second: fn((usize, &'r V)) -> &'r V = second; // coerce to fn pointer
2014-12-02 14:07:40 -05:00
Values { iter: self.iter().map(second) }
}
2015-01-19 11:06:15 +01:00
/// Returns an iterator visiting all key-value pairs in ascending order of the keys.
2015-02-04 21:17:19 -05:00
/// The iterator's element type is `(usize, &'r V)`.
2014-07-24 15:46:55 +02:00
///
/// # Examples
2014-07-24 15:46:55 +02:00
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
/// use std::collections::VecMap;
2014-07-24 15:46:55 +02:00
///
/// let mut map = VecMap::new();
2014-07-24 15:46:55 +02:00
/// 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);
/// }
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn iter<'r>(&'r self) -> Iter<'r, V> {
Iter {
front: 0,
back: self.v.len(),
iter: self.v.iter()
}
}
2015-01-19 11:06:15 +01:00
/// Returns an iterator visiting all key-value pairs in ascending order of the keys,
2014-08-04 22:48:39 +12:00
/// with mutable references to the values.
2015-02-04 21:17:19 -05:00
/// The iterator's element type is `(usize, &'r mut V)`.
2014-07-24 15:46:55 +02:00
///
/// # Examples
2014-07-24 15:46:55 +02:00
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
/// use std::collections::VecMap;
2014-07-24 15:46:55 +02:00
///
/// let mut map = VecMap::new();
2014-07-24 15:46:55 +02:00
/// map.insert(1, "a");
/// map.insert(2, "b");
/// map.insert(3, "c");
///
2014-09-14 20:27:36 -07:00
/// for (key, value) in map.iter_mut() {
2014-07-24 15:46:55 +02:00
/// *value = "x";
/// }
///
/// for (key, value) in map.iter() {
/// assert_eq!(value, &"x");
/// }
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn iter_mut<'r>(&'r mut self) -> IterMut<'r, V> {
IterMut {
front: 0,
back: self.v.len(),
2014-09-14 20:27:36 -07:00
iter: self.v.iter_mut()
}
}
/// Moves all elements from `other` into the map while overwriting existing keys.
///
/// # Examples
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut a = VecMap::new();
/// a.insert(1, "a");
/// a.insert(2, "b");
///
/// let mut b = VecMap::new();
/// b.insert(3, "c");
/// b.insert(4, "d");
///
/// a.append(&mut b);
///
/// assert_eq!(a.len(), 4);
/// assert_eq!(b.len(), 0);
/// assert_eq!(a[1], "a");
/// assert_eq!(a[2], "b");
/// assert_eq!(a[3], "c");
/// assert_eq!(a[4], "d");
/// ```
#[unstable(feature = "collections",
reason = "recently added as part of collections reform 2")]
pub fn append(&mut self, other: &mut Self) {
self.extend(other.drain());
}
/// Splits the collection into two at the given key.
///
/// Returns a newly allocated `Self`. `self` contains elements `[0, at)`,
/// and the returned `Self` contains elements `[at, max_key)`.
///
/// Note that the capacity of `self` does not change.
///
/// # Examples
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut a = VecMap::new();
/// a.insert(1, "a");
/// a.insert(2, "b");
/// a.insert(3, "c");
/// a.insert(4, "d");
///
/// let b = a.split_off(3);
///
/// assert_eq!(a[1], "a");
/// assert_eq!(a[2], "b");
///
/// assert_eq!(b[3], "c");
/// assert_eq!(b[4], "d");
/// ```
#[unstable(feature = "collections",
reason = "recently added as part of collections reform 2")]
pub fn split_off(&mut self, at: usize) -> Self {
let mut other = VecMap::new();
if at == 0 {
// Move all elements to other
swap(self, &mut other);
return other
} else if at > self.v.len() {
// No elements to copy
return other;
}
// Look up the index of the first non-None item
let first_index = self.v.iter().position(|el| el.is_some());
let start_index = match first_index {
Some(index) => max(at, index),
None => {
// self has no elements
return other;
}
};
// Fill the new VecMap with `None`s until `start_index`
other.v.extend((0..start_index).map(|_| None));
// Move elements beginning with `start_index` from `self` into `other`
other.v.extend(self.v[start_index..].iter_mut().map(|el| el.take()));
other
}
2015-01-19 11:06:15 +01:00
/// Returns an iterator visiting all key-value pairs in ascending order of
/// the keys, emptying (but not consuming) the original `VecMap`.
2015-02-04 21:17:19 -05:00
/// The iterator's element type is `(usize, &'r V)`. Keeps the allocated memory for reuse.
2015-01-19 11:06:15 +01:00
///
/// # Examples
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
2015-01-19 11:06:15 +01:00
/// use std::collections::VecMap;
///
/// let mut map = VecMap::new();
/// map.insert(1, "a");
/// map.insert(3, "c");
/// map.insert(2, "b");
///
2015-02-04 21:17:19 -05:00
/// let vec: Vec<(usize, &str)> = map.drain().collect();
2015-01-19 11:06:15 +01:00
///
2015-02-24 21:15:45 +03:00
/// assert_eq!(vec, [(1, "a"), (2, "b"), (3, "c")]);
2015-01-19 11:06:15 +01:00
/// ```
#[unstable(feature = "collections",
reason = "matches collection reform specification, waiting for dust to settle")]
2015-01-19 11:06:15 +01:00
pub fn drain<'a>(&'a mut self) -> Drain<'a, V> {
2015-02-04 21:17:19 -05:00
fn filter<A>((i, v): (usize, Option<A>)) -> Option<(usize, A)> {
2015-01-19 11:06:15 +01:00
v.map(|v| (i, v))
}
2015-02-04 21:17:19 -05:00
let filter: fn((usize, Option<V>)) -> Option<(usize, V)> = filter; // coerce to fn ptr
2015-01-19 11:06:15 +01:00
Drain { iter: self.v.drain().enumerate().filter_map(filter) }
}
/// Returns the number of elements in the map.
///
/// # Examples
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut a = VecMap::new();
/// assert_eq!(a.len(), 0);
/// a.insert(1, "a");
/// assert_eq!(a.len(), 1);
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
pub fn len(&self) -> usize {
self.v.iter().filter(|elt| elt.is_some()).count()
}
/// Returns true if the map contains no elements.
///
/// # Examples
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut a = VecMap::new();
/// assert!(a.is_empty());
/// a.insert(1, "a");
/// assert!(!a.is_empty());
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn is_empty(&self) -> bool {
self.v.iter().all(|elt| elt.is_none())
}
/// Clears the map, removing all key-value pairs.
///
/// # Examples
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut a = VecMap::new();
/// a.insert(1, "a");
/// a.clear();
/// assert!(a.is_empty());
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn clear(&mut self) { self.v.clear() }
/// Returns a reference to the value corresponding to the key.
///
/// # Examples
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
/// 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);
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
pub fn get(&self, key: &usize) -> 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
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
/// 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]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
pub fn contains_key(&self, key: &usize) -> bool {
self.get(key).is_some()
}
/// Returns a mutable reference to the value corresponding to the key.
///
/// # Examples
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut map = VecMap::new();
/// map.insert(1, "a");
/// if let Some(x) = map.get_mut(&1) {
/// *x = "b";
/// }
/// assert_eq!(map[1], "b");
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
pub fn get_mut(&mut self, key: &usize) -> 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 into the map. If the key already had a value
/// present in the map, that value is returned. Otherwise, `None` is returned.
///
/// # Examples
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
/// 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");
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
pub fn insert(&mut self, key: usize, value: V) -> Option<V> {
let len = self.v.len();
if len <= key {
self.v.extend((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
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
/// 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);
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
pub fn remove(&mut self, key: &usize) -> Option<V> {
if *key >= self.v.len() {
return None;
}
let result = &mut self.v[*key];
result.take()
}
2015-02-03 00:47:38 -05:00
/// Gets the given key's corresponding entry in the map for in-place manipulation.
///
/// # Examples
///
/// ```
2015-03-13 15:28:35 -07:00
/// # #![feature(collections)]
2015-02-03 00:47:38 -05:00
/// use std::collections::VecMap;
///
/// let mut count: VecMap<u32> = VecMap::new();
///
/// // count the number of occurrences of numbers in the vec
/// for x in vec![1, 2, 1, 2, 3, 4, 1, 2, 4] {
2015-03-20 13:43:01 -04:00
/// *count.entry(x).or_insert(0) += 1;
2015-02-03 00:47:38 -05:00
/// }
///
/// assert_eq!(count[1], 3);
/// ```
2015-02-04 19:36:02 -05:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-03 00:47:38 -05:00
pub fn entry(&mut self, key: usize) -> Entry<V> {
// FIXME(Gankro): this is basically the dumbest implementation of
// entry possible, because weird non-lexical borrows issues make it
// completely insane to do any other way. That said, Entry is a border-line
// useless construct on VecMap, so it's hardly a big loss.
if self.contains_key(&key) {
Occupied(OccupiedEntry {
map: self,
index: key,
})
} else {
Vacant(VacantEntry {
map: self,
index: key,
})
}
}
}
impl<'a, V> Entry<'a, V> {
#[unstable(feature = "collections",
reason = "will soon be replaced by or_insert")]
#[deprecated(since = "1.0",
2015-03-20 13:43:01 -04:00
reason = "replaced with more ergonomic `or_insert` and `or_insert_with`")]
2015-02-03 00:47:38 -05:00
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, V>> {
match self {
Occupied(entry) => Ok(entry.into_mut()),
Vacant(entry) => Err(entry),
}
}
#[unstable(feature = "collections",
reason = "matches entry v3 specification, waiting for dust to settle")]
/// Ensures a value is in the entry by inserting the default if empty, and returns
/// a mutable reference to the value in the entry.
2015-03-20 13:43:01 -04:00
pub fn or_insert(self, default: V) -> &'a mut V {
match self {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.insert(default),
}
}
#[unstable(feature = "collections",
reason = "matches entry v3 specification, waiting for dust to settle")]
/// Ensures a value is in the entry by inserting the result of the default function if empty,
/// and returns a mutable reference to the value in the entry.
2015-03-20 13:43:01 -04:00
pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
match self {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.insert(default()),
}
}
2015-02-03 00:47:38 -05:00
}
impl<'a, V> VacantEntry<'a, V> {
/// Sets the value of the entry with the VacantEntry's key,
/// and returns a mutable reference to it.
2015-02-04 19:36:02 -05:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-03 00:47:38 -05:00
pub fn insert(self, value: V) -> &'a mut V {
let index = self.index;
self.map.insert(index, value);
&mut self.map[index]
}
}
impl<'a, V> OccupiedEntry<'a, V> {
/// Gets a reference to the value in the entry.
2015-02-04 19:36:02 -05:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-03 00:47:38 -05:00
pub fn get(&self) -> &V {
let index = self.index;
&self.map[index]
}
/// Gets a mutable reference to the value in the entry.
2015-02-04 19:36:02 -05:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-03 00:47:38 -05:00
pub fn get_mut(&mut self) -> &mut V {
let index = self.index;
&mut self.map[index]
}
/// Converts the entry into a mutable reference to its value.
2015-02-04 19:36:02 -05:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-03 00:47:38 -05:00
pub fn into_mut(self) -> &'a mut V {
let index = self.index;
&mut self.map[index]
}
/// Sets the value of the entry with the OccupiedEntry's key,
/// and returns the entry's old value.
2015-02-04 19:36:02 -05:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-03 00:47:38 -05:00
pub fn insert(&mut self, value: V) -> V {
let index = self.index;
self.map.insert(index, value).unwrap()
}
/// Takes the value of the entry out of the map, and returns it.
2015-02-04 19:36:02 -05:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-03 00:47:38 -05:00
pub fn remove(self) -> V {
let index = self.index;
self.map.remove(&index).unwrap()
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<V: PartialEq> PartialEq for VecMap<V> {
fn eq(&self, other: &VecMap<V>) -> bool {
iter::order::eq(self.iter(), other.iter())
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<V: Eq> Eq for VecMap<V> {}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<V: PartialOrd> PartialOrd for VecMap<V> {
2014-07-28 00:00:29 -04:00
#[inline]
fn partial_cmp(&self, other: &VecMap<V>) -> Option<Ordering> {
2014-07-28 00:00:29 -04:00
iter::order::partial_cmp(self.iter(), other.iter())
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<V: Ord> Ord for VecMap<V> {
#[inline]
fn cmp(&self, other: &VecMap<V>) -> Ordering {
iter::order::cmp(self.iter(), other.iter())
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
std: Rename Show/String to Debug/Display This commit is an implementation of [RFC 565][rfc] which is a stabilization of the `std::fmt` module and the implementations of various formatting traits. Specifically, the following changes were performed: [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0565-show-string-guidelines.md * The `Show` trait is now deprecated, it was renamed to `Debug` * The `String` trait is now deprecated, it was renamed to `Display` * Many `Debug` and `Display` implementations were audited in accordance with the RFC and audited implementations now have the `#[stable]` attribute * Integers and floats no longer print a suffix * Smart pointers no longer print details that they are a smart pointer * Paths with `Debug` are now quoted and escape characters * The `unwrap` methods on `Result` now require `Display` instead of `Debug` * The `Error` trait no longer has a `detail` method and now requires that `Display` must be implemented. With the loss of `String`, this has moved into libcore. * `impl<E: Error> FromError<E> for Box<Error>` now exists * `derive(Show)` has been renamed to `derive(Debug)`. This is not currently warned about due to warnings being emitted on stage1+ While backwards compatibility is attempted to be maintained with a blanket implementation of `Display` for the old `String` trait (and the same for `Show`/`Debug`) this is still a breaking change due to primitives no longer implementing `String` as well as modifications such as `unwrap` and the `Error` trait. Most code is fairly straightforward to update with a rename or tweaks of method calls. [breaking-change] Closes #21436
2015-01-20 15:45:07 -08:00
impl<V: fmt::Debug> fmt::Debug for VecMap<V> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "{{"));
for (i, (k, v)) in self.iter().enumerate() {
if i != 0 { try!(write!(f, ", ")); }
try!(write!(f, "{}: {:?}", k, *v));
}
write!(f, "}}")
}
2014-06-07 18:17:58 +02:00
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
impl<V> FromIterator<(usize, V)> for VecMap<V> {
fn from_iter<I: IntoIterator<Item=(usize, V)>>(iter: I) -> VecMap<V> {
let mut map = VecMap::new();
map.extend(iter);
map
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> IntoIterator for VecMap<T> {
type Item = (usize, T);
type IntoIter = IntoIter<T>;
/// Returns an iterator visiting all key-value pairs in ascending order of
/// the keys, consuming the original `VecMap`.
/// The iterator's element type is `(usize, &'r V)`.
///
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut map = VecMap::new();
/// map.insert(1, "a");
/// map.insert(3, "c");
/// map.insert(2, "b");
///
/// let vec: Vec<(usize, &str)> = map.into_iter().collect();
///
/// assert_eq!(vec, [(1, "a"), (2, "b"), (3, "c")]);
/// ```
fn into_iter(self) -> IntoIter<T> {
fn filter<A>((i, v): (usize, Option<A>)) -> Option<(usize, A)> {
v.map(|v| (i, v))
}
let filter: fn((usize, Option<T>)) -> Option<(usize, T)> = filter; // coerce to fn ptr
IntoIter { iter: self.v.into_iter().enumerate().filter_map(filter) }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-07 22:01:05 -05:00
impl<'a, T> IntoIterator for &'a VecMap<T> {
type Item = (usize, &'a T);
type IntoIter = Iter<'a, T>;
2015-01-07 22:01:05 -05:00
fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-07 22:01:05 -05:00
impl<'a, T> IntoIterator for &'a mut VecMap<T> {
type Item = (usize, &'a mut T);
type IntoIter = IterMut<'a, T>;
2015-01-07 22:01:05 -05:00
fn into_iter(mut self) -> IterMut<'a, T> {
self.iter_mut()
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
impl<V> Extend<(usize, V)> for VecMap<V> {
fn extend<I: IntoIterator<Item=(usize, V)>>(&mut self, iter: I) {
for (k, v) in iter {
self.insert(k, v);
}
}
}
impl<V> Index<usize> for VecMap<V> {
type Output = V;
#[inline]
fn index<'a>(&'a self, i: usize) -> &'a V {
self.get(&i).expect("key not present")
}
}
impl<'a,V> Index<&'a usize> for VecMap<V> {
type Output = V;
#[inline]
fn index(&self, i: &usize) -> &V {
self.get(i).expect("key not present")
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
impl<V> IndexMut<usize> for VecMap<V> {
2015-01-03 10:40:10 -05:00
#[inline]
fn index_mut(&mut self, i: usize) -> &mut V {
self.get_mut(&i).expect("key not present")
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, V> IndexMut<&'a usize> for VecMap<V> {
#[inline]
fn index_mut(&mut self, i: &usize) -> &mut V {
2015-01-03 10:40:10 -05:00
self.get_mut(i).expect("key not present")
}
}
macro_rules! iterator {
(impl $name:ident -> $elem:ty, $($getter:ident),+) => {
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-01 23:15:35 -05:00
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]
2015-02-04 21:17:19 -05:00
fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(self.back - self.front))
}
}
}
}
macro_rules! double_ended_iterator {
(impl $name:ident -> $elem:ty, $($getter:ident),+) => {
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-01 23:15:35 -05:00
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.
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Iter<'a, V:'a> {
2015-02-04 21:17:19 -05:00
front: usize,
back: usize,
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()
}
}
}
2015-02-04 21:17:19 -05:00
iterator! { impl Iter -> (usize, &'a V), as_ref }
double_ended_iterator! { impl Iter -> (usize, &'a V), as_ref }
/// An iterator over the key-value pairs of a map, with the
2014-07-24 15:46:55 +02:00
/// values being mutable.
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IterMut<'a, V:'a> {
2015-02-04 21:17:19 -05:00
front: usize,
back: usize,
iter: slice::IterMut<'a, Option<V>>
}
2015-02-04 21:17:19 -05:00
iterator! { impl IterMut -> (usize, &'a mut V), as_mut }
double_ended_iterator! { impl IterMut -> (usize, &'a mut V), as_mut }
/// An iterator over the keys of a map.
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Keys<'a, V: 'a> {
2015-02-04 21:17:19 -05:00
iter: Map<Iter<'a, V>, fn((usize, &'a V)) -> usize>
}
// 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.
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Values<'a, V: 'a> {
2015-02-04 21:17:19 -05:00
iter: Map<Iter<'a, V>, fn((usize, &'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.
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IntoIter<V> {
iter: FilterMap<
Enumerate<vec::IntoIter<Option<V>>>,
2015-02-04 21:17:19 -05:00
fn((usize, Option<V>)) -> Option<(usize, V)>>
}
#[unstable(feature = "collections")]
2015-02-12 10:30:39 -05:00
pub struct Drain<'a, V:'a> {
2015-01-19 11:06:15 +01:00
iter: FilterMap<
Enumerate<vec::Drain<'a, Option<V>>>,
2015-02-04 21:17:19 -05:00
fn((usize, Option<V>)) -> Option<(usize, V)>>
2015-01-19 11:06:15 +01:00
}
#[unstable(feature = "collections")]
2015-01-19 11:06:15 +01:00
impl<'a, V> Iterator for Drain<'a, V> {
2015-02-04 21:17:19 -05:00
type Item = (usize, V);
2015-01-19 11:06:15 +01:00
2015-02-04 21:17:19 -05:00
fn next(&mut self) -> Option<(usize, V)> { self.iter.next() }
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
2015-01-19 11:06:15 +01:00
}
#[unstable(feature = "collections")]
2015-01-19 11:06:15 +01:00
impl<'a, V> DoubleEndedIterator for Drain<'a, V> {
2015-02-04 21:17:19 -05:00
fn next_back(&mut self) -> Option<(usize, V)> { self.iter.next_back() }
2015-01-19 11:06:15 +01:00
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-01 23:15:35 -05:00
impl<'a, V> Iterator for Keys<'a, V> {
2015-02-04 21:17:19 -05:00
type Item = usize;
2015-01-01 23:15:35 -05:00
2015-02-04 21:17:19 -05:00
fn next(&mut self) -> Option<usize> { self.iter.next() }
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-01 23:15:35 -05:00
impl<'a, V> DoubleEndedIterator for Keys<'a, V> {
2015-02-04 21:17:19 -05:00
fn next_back(&mut self) -> Option<usize> { self.iter.next_back() }
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-01 23:15:35 -05:00
impl<'a, V> Iterator for Values<'a, V> {
type Item = &'a V;
fn next(&mut self) -> Option<(&'a V)> { self.iter.next() }
2015-02-04 21:17:19 -05:00
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-01 23:15:35 -05:00
impl<'a, V> DoubleEndedIterator for Values<'a, V> {
fn next_back(&mut self) -> Option<(&'a V)> { self.iter.next_back() }
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-01 23:15:35 -05:00
impl<V> Iterator for IntoIter<V> {
2015-02-04 21:17:19 -05:00
type Item = (usize, V);
2015-01-01 23:15:35 -05:00
2015-02-04 21:17:19 -05:00
fn next(&mut self) -> Option<(usize, V)> { self.iter.next() }
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-01 23:15:35 -05:00
impl<V> DoubleEndedIterator for IntoIter<V> {
2015-02-04 21:17:19 -05:00
fn next_back(&mut self) -> Option<(usize, V)> { self.iter.next_back() }
}