1
Fork 0

Implement Index for HashMap

This also deprecates HashMap::get. Use indexing instead.
This commit is contained in:
P1start 2014-08-02 18:48:44 +12:00
parent fd10d209cd
commit 32f5898bea
4 changed files with 57 additions and 15 deletions

View file

@ -166,7 +166,7 @@ fn resolved_path(w: &mut fmt::Formatter, did: ast::DefId, p: &clean::Path,
if ast_util::is_local(did) || cache.inlined.contains(&did) { if ast_util::is_local(did) || cache.inlined.contains(&did) {
Some(("../".repeat(loc.len())).to_string()) Some(("../".repeat(loc.len())).to_string())
} else { } else {
match *cache.extern_locations.get(&did.krate) { match cache.extern_locations[did.krate] {
render::Remote(ref s) => Some(s.to_string()), render::Remote(ref s) => Some(s.to_string()),
render::Local => { render::Local => {
Some(("../".repeat(loc.len())).to_string()) Some(("../".repeat(loc.len())).to_string())
@ -291,11 +291,11 @@ fn primitive_link(f: &mut fmt::Formatter,
needs_termination = true; needs_termination = true;
} }
Some(&cnum) => { Some(&cnum) => {
let path = m.paths.get(&ast::DefId { let path = &m.paths[ast::DefId {
krate: cnum, krate: cnum,
node: ast::CRATE_NODE_ID, node: ast::CRATE_NODE_ID,
}); }];
let loc = match *m.extern_locations.get(&cnum) { let loc = match m.extern_locations[cnum] {
render::Remote(ref s) => Some(s.to_string()), render::Remote(ref s) => Some(s.to_string()),
render::Local => { render::Local => {
let loc = current_location_key.get().unwrap(); let loc = current_location_key.get().unwrap();
@ -343,11 +343,11 @@ impl fmt::Show for clean::Type {
match *self { match *self {
clean::TyParamBinder(id) => { clean::TyParamBinder(id) => {
let m = cache_key.get().unwrap(); let m = cache_key.get().unwrap();
f.write(m.typarams.get(&ast_util::local_def(id)).as_bytes()) f.write(m.typarams[ast_util::local_def(id)].as_bytes())
} }
clean::Generic(did) => { clean::Generic(did) => {
let m = cache_key.get().unwrap(); let m = cache_key.get().unwrap();
f.write(m.typarams.get(&did).as_bytes()) f.write(m.typarams[did].as_bytes())
} }
clean::ResolvedPath{ did, ref typarams, ref path } => { clean::ResolvedPath{ did, ref typarams, ref path } => {
try!(resolved_path(f, did, path, false)); try!(resolved_path(f, did, path, false));

View file

@ -1252,8 +1252,8 @@ impl<'a> Item<'a> {
// located, then we return `None`. // located, then we return `None`.
} else { } else {
let cache = cache_key.get().unwrap(); let cache = cache_key.get().unwrap();
let path = cache.external_paths.get(&self.item.def_id); let path = &cache.external_paths[self.item.def_id];
let root = match *cache.extern_locations.get(&self.item.def_id.krate) { let root = match cache.extern_locations[self.item.def_id.krate] {
Remote(ref s) => s.to_string(), Remote(ref s) => s.to_string(),
Local => self.cx.root_path.clone(), Local => self.cx.root_path.clone(),
Unknown => return None, Unknown => return None,

View file

@ -229,7 +229,7 @@ impl<'a> RustdocVisitor<'a> {
core::Typed(ref tcx) => tcx, core::Typed(ref tcx) => tcx,
core::NotTyped(_) => return false core::NotTyped(_) => return false
}; };
let def = tcx.def_map.borrow().get(&id).def_id(); let def = (*tcx.def_map.borrow())[id].def_id();
if !ast_util::is_local(def) { return false } if !ast_util::is_local(def) { return false }
let analysis = match self.analysis { let analysis = match self.analysis {
Some(analysis) => analysis, None => return false Some(analysis) => analysis, None => return false

View file

@ -26,6 +26,7 @@ use mem::replace;
use num; use num;
use option::{Some, None, Option}; use option::{Some, None, Option};
use result::{Ok, Err}; use result::{Ok, Err};
use ops::Index;
mod table { mod table {
use clone::Clone; use clone::Clone;
@ -1341,7 +1342,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
/// ///
/// // Update and return the existing value /// // Update and return the existing value
/// assert_eq!(*map.insert_or_update_with("a", 9, |_key, val| *val = 7), 7); /// assert_eq!(*map.insert_or_update_with("a", 9, |_key, val| *val = 7), 7);
/// assert_eq!(map.get(&"a"), &7); /// assert_eq!(map["a"], 7);
/// ``` /// ```
pub fn insert_or_update_with<'a>( pub fn insert_or_update_with<'a>(
&'a mut self, &'a mut self,
@ -1392,9 +1393,9 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
/// } /// }
/// ///
/// assert_eq!(map.len(), 3); /// assert_eq!(map.len(), 3);
/// assert_eq!(map.get(&"a key"), &vec!["value", "new value"]); /// assert_eq!(map["a key"], vec!["value", "new value"]);
/// assert_eq!(map.get(&"b key"), &vec!["new value"]); /// assert_eq!(map["b key"], vec!["new value"]);
/// assert_eq!(map.get(&"z key"), &vec!["new value", "value"]); /// assert_eq!(map["z key"], vec!["new value", "value"]);
/// ``` /// ```
pub fn find_with_or_insert_with<'a, A>(&'a mut self, pub fn find_with_or_insert_with<'a, A>(&'a mut self,
k: K, k: K,
@ -1426,12 +1427,15 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// #![allow(deprecated)]
///
/// use std::collections::HashMap; /// use std::collections::HashMap;
/// ///
/// let mut map = HashMap::new(); /// let mut map = HashMap::new();
/// map.insert("a", 1i); /// map.insert("a", 1i);
/// assert_eq!(map.get(&"a"), &1); /// assert_eq!(map.get(&"a"), &1);
/// ``` /// ```
#[deprecated = "prefer indexing instead, e.g., map[key]"]
pub fn get<'a>(&'a self, k: &K) -> &'a V { pub fn get<'a>(&'a self, k: &K) -> &'a V {
match self.find(k) { match self.find(k) {
Some(v) => v, Some(v) => v,
@ -1458,11 +1462,11 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
/// let val = map.get_mut(&"a"); /// let val = map.get_mut(&"a");
/// *val = 40; /// *val = 40;
/// } /// }
/// assert_eq!(map.get(&"a"), &40); /// assert_eq!(map["a"], 40);
/// ///
/// // A more direct way could be: /// // A more direct way could be:
/// *map.get_mut(&"a") = -2; /// *map.get_mut(&"a") = -2;
/// assert_eq!(map.get(&"a"), &-2); /// assert_eq!(map["a"], -2);
/// ``` /// ```
pub fn get_mut<'a>(&'a mut self, k: &K) -> &'a mut V { pub fn get_mut<'a>(&'a mut self, k: &K) -> &'a mut V {
match self.find_mut(k) { match self.find_mut(k) {
@ -1738,6 +1742,21 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Default for HashMap<K, V, H>
} }
} }
impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Index<K, V> for HashMap<K, V, H> {
#[inline]
fn index<'a>(&'a self, index: &K) -> &'a V {
self.get(index)
}
}
// FIXME(#12825) Indexing will always try IndexMut first and that causes issues.
/*impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> ops::IndexMut<K, V> for HashMap<K, V, H> {
#[inline]
fn index_mut<'a>(&'a mut self, index: &K) -> &'a mut V {
self.get_mut(index)
}
}*/
/// HashMap iterator /// HashMap iterator
pub type Entries<'a, K, V> = table::Entries<'a, K, V>; pub type Entries<'a, K, V> = table::Entries<'a, K, V>;
@ -2694,6 +2713,29 @@ mod test_map {
assert_eq!(iter.size_hint(), (3, Some(3))); assert_eq!(iter.size_hint(), (3, Some(3)));
} }
#[test]
fn test_index() {
let mut map: HashMap<int, int> = HashMap::new();
map.insert(1, 2);
map.insert(2, 1);
map.insert(3, 4);
assert_eq!(map[2], 1);
}
#[test]
#[should_fail]
fn test_index_nonexistent() {
let mut map: HashMap<int, int> = HashMap::new();
map.insert(1, 2);
map.insert(2, 1);
map.insert(3, 4);
map[4];
}
} }
#[cfg(test)] #[cfg(test)]