[breaking change] Revert Entry behaviour to take keys by value.
This commit is contained in:
@@ -19,7 +19,7 @@ pub use self::Entry::*;
|
|||||||
|
|
||||||
use core::prelude::*;
|
use core::prelude::*;
|
||||||
|
|
||||||
use core::borrow::{BorrowFrom, ToOwned};
|
use core::borrow::BorrowFrom;
|
||||||
use core::cmp::Ordering;
|
use core::cmp::Ordering;
|
||||||
use core::default::Default;
|
use core::default::Default;
|
||||||
use core::fmt::Show;
|
use core::fmt::Show;
|
||||||
@@ -130,17 +130,17 @@ pub struct Values<'a, K: 'a, V: 'a> {
|
|||||||
|
|
||||||
#[stable]
|
#[stable]
|
||||||
/// A view into a single entry in a map, which may either be vacant or occupied.
|
/// A view into a single entry in a map, which may either be vacant or occupied.
|
||||||
pub enum Entry<'a, Q: ?Sized +'a, K:'a, V:'a> {
|
pub enum Entry<'a, K:'a, V:'a> {
|
||||||
/// A vacant Entry
|
/// A vacant Entry
|
||||||
Vacant(VacantEntry<'a, Q, K, V>),
|
Vacant(VacantEntry<'a, K, V>),
|
||||||
/// An occupied Entry
|
/// An occupied Entry
|
||||||
Occupied(OccupiedEntry<'a, K, V>),
|
Occupied(OccupiedEntry<'a, K, V>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable]
|
#[stable]
|
||||||
/// A vacant Entry.
|
/// A vacant Entry.
|
||||||
pub struct VacantEntry<'a, Q: ?Sized +'a, K:'a, V:'a> {
|
pub struct VacantEntry<'a, K:'a, V:'a> {
|
||||||
key: &'a Q,
|
key: K,
|
||||||
stack: stack::SearchStack<'a, K, V, node::handle::Edge, node::handle::Leaf>,
|
stack: stack::SearchStack<'a, K, V, node::handle::Edge, node::handle::Leaf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1111,10 +1111,10 @@ impl<'a, K, V> DoubleEndedIterator for Values<'a, K, V> {
|
|||||||
#[stable]
|
#[stable]
|
||||||
impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {}
|
impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {}
|
||||||
|
|
||||||
impl<'a, Q: ?Sized, K: Ord, V> Entry<'a, Q, K, V> {
|
impl<'a, K: Ord, V> Entry<'a, K, V> {
|
||||||
#[unstable = "matches collection reform v2 specification, waiting for dust to settle"]
|
#[unstable = "matches collection reform v2 specification, waiting for dust to settle"]
|
||||||
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
|
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
|
||||||
pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, Q, K, V>> {
|
pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, K, V>> {
|
||||||
match self {
|
match self {
|
||||||
Occupied(entry) => Ok(entry.into_mut()),
|
Occupied(entry) => Ok(entry.into_mut()),
|
||||||
Vacant(entry) => Err(entry),
|
Vacant(entry) => Err(entry),
|
||||||
@@ -1122,12 +1122,12 @@ impl<'a, Q: ?Sized, K: Ord, V> Entry<'a, Q, K, V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Q: ?Sized + ToOwned<K>, K: Ord, V> VacantEntry<'a, Q, K, V> {
|
impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
|
||||||
#[stable]
|
#[stable]
|
||||||
/// Sets the value of the entry with the VacantEntry's key,
|
/// Sets the value of the entry with the VacantEntry's key,
|
||||||
/// and returns a mutable reference to it.
|
/// and returns a mutable reference to it.
|
||||||
pub fn insert(self, value: V) -> &'a mut V {
|
pub fn insert(self, value: V) -> &'a mut V {
|
||||||
self.stack.insert(self.key.to_owned(), value)
|
self.stack.insert(self.key, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1362,14 +1362,12 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
/// ```
|
/// ```
|
||||||
/// The key must have the same ordering before or after `.to_owned()` is called.
|
/// The key must have the same ordering before or after `.to_owned()` is called.
|
||||||
#[stable]
|
#[stable]
|
||||||
pub fn entry<'a, Q: ?Sized>(&'a mut self, mut key: &'a Q) -> Entry<'a, Q, K, V>
|
pub fn entry<'a>(&'a mut self, mut key: K) -> Entry<'a, K, V> {
|
||||||
where Q: Ord + ToOwned<K>
|
|
||||||
{
|
|
||||||
// same basic logic of `swap` and `pop`, blended together
|
// same basic logic of `swap` and `pop`, blended together
|
||||||
let mut stack = stack::PartialSearchStack::new(self);
|
let mut stack = stack::PartialSearchStack::new(self);
|
||||||
loop {
|
loop {
|
||||||
let result = stack.with(move |pusher, node| {
|
let result = stack.with(move |pusher, node| {
|
||||||
return match Node::search(node, key) {
|
return match Node::search(node, &key) {
|
||||||
Found(handle) => {
|
Found(handle) => {
|
||||||
// Perfect match
|
// Perfect match
|
||||||
Finished(Occupied(OccupiedEntry {
|
Finished(Occupied(OccupiedEntry {
|
||||||
@@ -1412,7 +1410,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
use std::borrow::{ToOwned, BorrowFrom};
|
use std::borrow::BorrowFrom;
|
||||||
|
|
||||||
use super::{BTreeMap, Occupied, Vacant};
|
use super::{BTreeMap, Occupied, Vacant};
|
||||||
|
|
||||||
@@ -1562,7 +1560,7 @@ mod test {
|
|||||||
let mut map: BTreeMap<int, int> = xs.iter().map(|&x| x).collect();
|
let mut map: BTreeMap<int, int> = xs.iter().map(|&x| x).collect();
|
||||||
|
|
||||||
// Existing key (insert)
|
// Existing key (insert)
|
||||||
match map.entry(&1) {
|
match map.entry(1) {
|
||||||
Vacant(_) => unreachable!(),
|
Vacant(_) => unreachable!(),
|
||||||
Occupied(mut view) => {
|
Occupied(mut view) => {
|
||||||
assert_eq!(view.get(), &10);
|
assert_eq!(view.get(), &10);
|
||||||
@@ -1574,7 +1572,7 @@ mod test {
|
|||||||
|
|
||||||
|
|
||||||
// Existing key (update)
|
// Existing key (update)
|
||||||
match map.entry(&2) {
|
match map.entry(2) {
|
||||||
Vacant(_) => unreachable!(),
|
Vacant(_) => unreachable!(),
|
||||||
Occupied(mut view) => {
|
Occupied(mut view) => {
|
||||||
let v = view.get_mut();
|
let v = view.get_mut();
|
||||||
@@ -1585,7 +1583,7 @@ mod test {
|
|||||||
assert_eq!(map.len(), 6);
|
assert_eq!(map.len(), 6);
|
||||||
|
|
||||||
// Existing key (take)
|
// Existing key (take)
|
||||||
match map.entry(&3) {
|
match map.entry(3) {
|
||||||
Vacant(_) => unreachable!(),
|
Vacant(_) => unreachable!(),
|
||||||
Occupied(view) => {
|
Occupied(view) => {
|
||||||
assert_eq!(view.remove(), 30);
|
assert_eq!(view.remove(), 30);
|
||||||
@@ -1596,7 +1594,7 @@ mod test {
|
|||||||
|
|
||||||
|
|
||||||
// Inexistent key (insert)
|
// Inexistent key (insert)
|
||||||
match map.entry(&10) {
|
match map.entry(10) {
|
||||||
Occupied(_) => unreachable!(),
|
Occupied(_) => unreachable!(),
|
||||||
Vacant(view) => {
|
Vacant(view) => {
|
||||||
assert_eq!(*view.insert(1000), 1000);
|
assert_eq!(*view.insert(1000), 1000);
|
||||||
|
|||||||
@@ -1328,7 +1328,7 @@ impl UnusedMut {
|
|||||||
let ident = path1.node;
|
let ident = path1.node;
|
||||||
if let ast::BindByValue(ast::MutMutable) = mode {
|
if let ast::BindByValue(ast::MutMutable) = mode {
|
||||||
if !token::get_ident(ident).get().starts_with("_") {
|
if !token::get_ident(ident).get().starts_with("_") {
|
||||||
match mutables.entry(&ident.name.uint()) {
|
match mutables.entry(ident.name.uint()) {
|
||||||
Vacant(entry) => { entry.insert(vec![id]); },
|
Vacant(entry) => { entry.insert(vec![id]); },
|
||||||
Occupied(mut entry) => { entry.get_mut().push(id); },
|
Occupied(mut entry) => { entry.get_mut().push(id); },
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -400,7 +400,7 @@ impl<'a> Context<'a> {
|
|||||||
info!("lib candidate: {}", path.display());
|
info!("lib candidate: {}", path.display());
|
||||||
|
|
||||||
let hash_str = hash.to_string();
|
let hash_str = hash.to_string();
|
||||||
let slot = candidates.entry(&hash_str).get().unwrap_or_else(
|
let slot = candidates.entry(hash_str).get().unwrap_or_else(
|
||||||
|vacant_entry| vacant_entry.insert((HashSet::new(), HashSet::new())));
|
|vacant_entry| vacant_entry.insert((HashSet::new(), HashSet::new())));
|
||||||
let (ref mut rlibs, ref mut dylibs) = *slot;
|
let (ref mut rlibs, ref mut dylibs) = *slot;
|
||||||
if rlib {
|
if rlib {
|
||||||
|
|||||||
@@ -311,7 +311,7 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr) -> P<ast::Pat> {
|
|||||||
|
|
||||||
ast::ExprCall(ref callee, ref args) => {
|
ast::ExprCall(ref callee, ref args) => {
|
||||||
let def = tcx.def_map.borrow()[callee.id].clone();
|
let def = tcx.def_map.borrow()[callee.id].clone();
|
||||||
if let Vacant(entry) = tcx.def_map.borrow_mut().entry(&expr.id) {
|
if let Vacant(entry) = tcx.def_map.borrow_mut().entry(expr.id) {
|
||||||
entry.insert(def);
|
entry.insert(def);
|
||||||
}
|
}
|
||||||
let path = match def {
|
let path = match def {
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
|
|||||||
None => { }
|
None => { }
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.freshen_map.entry(&key) {
|
match self.freshen_map.entry(key) {
|
||||||
Entry::Occupied(entry) => *entry.get(),
|
Entry::Occupied(entry) => *entry.get(),
|
||||||
Entry::Vacant(entry) => {
|
Entry::Vacant(entry) => {
|
||||||
let index = self.freshen_count;
|
let index = self.freshen_count;
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> {
|
|||||||
let mut node_ids = FnvHashMap::new();
|
let mut node_ids = FnvHashMap::new();
|
||||||
{
|
{
|
||||||
let mut add_node = |&mut : node| {
|
let mut add_node = |&mut : node| {
|
||||||
if let Vacant(e) = node_ids.entry(&node) {
|
if let Vacant(e) = node_ids.entry(node) {
|
||||||
e.insert(i);
|
e.insert(i);
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -437,11 +437,9 @@ fn register_region_obligation<'tcx>(tcx: &ty::ctxt<'tcx>,
|
|||||||
debug!("register_region_obligation({})",
|
debug!("register_region_obligation({})",
|
||||||
region_obligation.repr(tcx));
|
region_obligation.repr(tcx));
|
||||||
|
|
||||||
let body_id = region_obligation.cause.body_id;
|
match region_obligations.entry(region_obligation.cause.body_id) {
|
||||||
match region_obligations.entry(&body_id) {
|
|
||||||
Vacant(entry) => { entry.insert(vec![region_obligation]); },
|
Vacant(entry) => { entry.insert(vec![region_obligation]); },
|
||||||
Occupied(mut entry) => { entry.get_mut().push(region_obligation); },
|
Occupied(mut entry) => { entry.get_mut().push(region_obligation); },
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5584,7 +5584,7 @@ pub fn lookup_field_type<'tcx>(tcx: &ctxt<'tcx>,
|
|||||||
node_id_to_type(tcx, id.node)
|
node_id_to_type(tcx, id.node)
|
||||||
} else {
|
} else {
|
||||||
let mut tcache = tcx.tcache.borrow_mut();
|
let mut tcache = tcx.tcache.borrow_mut();
|
||||||
let pty = tcache.entry(&id).get().unwrap_or_else(
|
let pty = tcache.entry(id).get().unwrap_or_else(
|
||||||
|vacant_entry| vacant_entry.insert(csearch::get_field_type(tcx, struct_id, id)));
|
|vacant_entry| vacant_entry.insert(csearch::get_field_type(tcx, struct_id, id)));
|
||||||
pty.ty
|
pty.ty
|
||||||
};
|
};
|
||||||
@@ -6747,7 +6747,7 @@ pub fn replace_late_bound_regions<'tcx, T, F>(
|
|||||||
debug!("region={}", region.repr(tcx));
|
debug!("region={}", region.repr(tcx));
|
||||||
match region {
|
match region {
|
||||||
ty::ReLateBound(debruijn, br) if debruijn.depth == current_depth => {
|
ty::ReLateBound(debruijn, br) if debruijn.depth == current_depth => {
|
||||||
* map.entry(&br).get().unwrap_or_else(
|
* map.entry(br).get().unwrap_or_else(
|
||||||
|vacant_entry| vacant_entry.insert(mapf(br, debruijn)))
|
|vacant_entry| vacant_entry.insert(mapf(br, debruijn)))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|||||||
@@ -1115,7 +1115,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
|||||||
None => early_error("--extern value must be of the format `foo=bar`"),
|
None => early_error("--extern value must be of the format `foo=bar`"),
|
||||||
};
|
};
|
||||||
|
|
||||||
match externs.entry(&name.to_string()) {
|
match externs.entry(name.to_string()) {
|
||||||
Vacant(entry) => { entry.insert(vec![location.to_string()]); },
|
Vacant(entry) => { entry.insert(vec![location.to_string()]); },
|
||||||
Occupied(mut entry) => { entry.get_mut().push(location.to_string()); },
|
Occupied(mut entry) => { entry.get_mut().push(location.to_string()); },
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1701,7 +1701,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||||||
let is_public = import_directive.is_public;
|
let is_public = import_directive.is_public;
|
||||||
|
|
||||||
let mut import_resolutions = module_.import_resolutions.borrow_mut();
|
let mut import_resolutions = module_.import_resolutions.borrow_mut();
|
||||||
let dest_import_resolution = import_resolutions.entry(&name).get().unwrap_or_else(
|
let dest_import_resolution = import_resolutions.entry(name).get().unwrap_or_else(
|
||||||
|vacant_entry| {
|
|vacant_entry| {
|
||||||
// Create a new import resolution from this child.
|
// Create a new import resolution from this child.
|
||||||
vacant_entry.insert(ImportResolution::new(id, is_public))
|
vacant_entry.insert(ImportResolution::new(id, is_public))
|
||||||
@@ -2639,14 +2639,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||||||
def = DefUpvar(node_id, function_id, last_proc_body_id);
|
def = DefUpvar(node_id, function_id, last_proc_body_id);
|
||||||
|
|
||||||
let mut seen = self.freevars_seen.borrow_mut();
|
let mut seen = self.freevars_seen.borrow_mut();
|
||||||
let seen = match seen.entry(&function_id) {
|
let seen = match seen.entry(function_id) {
|
||||||
Occupied(v) => v.into_mut(),
|
Occupied(v) => v.into_mut(),
|
||||||
Vacant(v) => v.insert(NodeSet::new()),
|
Vacant(v) => v.insert(NodeSet::new()),
|
||||||
};
|
};
|
||||||
if seen.contains(&node_id) {
|
if seen.contains(&node_id) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
match self.freevars.borrow_mut().entry(&function_id) {
|
match self.freevars.borrow_mut().entry(function_id) {
|
||||||
Occupied(v) => v.into_mut(),
|
Occupied(v) => v.into_mut(),
|
||||||
Vacant(v) => v.insert(vec![]),
|
Vacant(v) => v.insert(vec![]),
|
||||||
}.push(Freevar { def: prev_def, span: span });
|
}.push(Freevar { def: prev_def, span: span });
|
||||||
@@ -4723,7 +4723,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||||||
"Import should only be used for `use` directives");
|
"Import should only be used for `use` directives");
|
||||||
self.last_private.insert(node_id, lp);
|
self.last_private.insert(node_id, lp);
|
||||||
|
|
||||||
match self.def_map.borrow_mut().entry(&node_id) {
|
match self.def_map.borrow_mut().entry(node_id) {
|
||||||
// Resolve appears to "resolve" the same ID multiple
|
// Resolve appears to "resolve" the same ID multiple
|
||||||
// times, so here is a sanity check it at least comes to
|
// times, so here is a sanity check it at least comes to
|
||||||
// the same conclusion! - nmatsakis
|
// the same conclusion! - nmatsakis
|
||||||
|
|||||||
@@ -603,7 +603,7 @@ pub fn check_struct_pat_fields<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
|
|||||||
|
|
||||||
// Typecheck each field.
|
// Typecheck each field.
|
||||||
for &Spanned { node: ref field, span } in fields.iter() {
|
for &Spanned { node: ref field, span } in fields.iter() {
|
||||||
let field_type = match used_fields.entry(&field.ident.name) {
|
let field_type = match used_fields.entry(field.ident.name) {
|
||||||
Occupied(occupied) => {
|
Occupied(occupied) => {
|
||||||
span_err!(tcx.sess, span, E0025,
|
span_err!(tcx.sess, span, E0025,
|
||||||
"field `{}` bound multiple times in the pattern",
|
"field `{}` bound multiple times in the pattern",
|
||||||
|
|||||||
@@ -821,7 +821,7 @@ impl DocFolder for Cache {
|
|||||||
if let clean::ImplItem(ref i) = item.inner {
|
if let clean::ImplItem(ref i) = item.inner {
|
||||||
match i.trait_ {
|
match i.trait_ {
|
||||||
Some(clean::ResolvedPath{ did, .. }) => {
|
Some(clean::ResolvedPath{ did, .. }) => {
|
||||||
let v = self.implementors.entry(&did).get().unwrap_or_else(
|
let v = self.implementors.entry(did).get().unwrap_or_else(
|
||||||
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
|
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
|
||||||
v.push(Implementor {
|
v.push(Implementor {
|
||||||
def_id: item.def_id,
|
def_id: item.def_id,
|
||||||
@@ -1011,7 +1011,7 @@ impl DocFolder for Cache {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(did) = did {
|
if let Some(did) = did {
|
||||||
let v = self.impls.entry(&did).get().unwrap_or_else(
|
let v = self.impls.entry(did).get().unwrap_or_else(
|
||||||
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
|
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
|
||||||
v.push(Impl {
|
v.push(Impl {
|
||||||
impl_: i,
|
impl_: i,
|
||||||
@@ -1260,7 +1260,7 @@ impl Context {
|
|||||||
Some(ref s) => s.to_string(),
|
Some(ref s) => s.to_string(),
|
||||||
};
|
};
|
||||||
let short = short.to_string();
|
let short = short.to_string();
|
||||||
let v = map.entry(&short).get().unwrap_or_else(
|
let v = map.entry(short).get().unwrap_or_else(
|
||||||
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
|
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
|
||||||
v.push(myname);
|
v.push(myname);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -330,7 +330,7 @@ fn parse_externs(matches: &getopts::Matches) -> Result<core::Externs, String> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
let name = name.to_string();
|
let name = name.to_string();
|
||||||
let locs = externs.entry(&name).get().unwrap_or_else(
|
let locs = externs.entry(name).get().unwrap_or_else(
|
||||||
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
|
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
|
||||||
locs.push(location.to_string());
|
locs.push(location.to_string());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use self::Entry::*;
|
|||||||
use self::SearchResult::*;
|
use self::SearchResult::*;
|
||||||
use self::VacantEntryState::*;
|
use self::VacantEntryState::*;
|
||||||
|
|
||||||
use borrow::{BorrowFrom, ToOwned};
|
use borrow::BorrowFrom;
|
||||||
use clone::Clone;
|
use clone::Clone;
|
||||||
use cmp::{max, Eq, PartialEq};
|
use cmp::{max, Eq, PartialEq};
|
||||||
use default::Default;
|
use default::Default;
|
||||||
@@ -922,14 +922,12 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
|
|||||||
|
|
||||||
#[stable]
|
#[stable]
|
||||||
/// Gets the given key's corresponding entry in the map for in-place manipulation.
|
/// Gets the given key's corresponding entry in the map for in-place manipulation.
|
||||||
/// Regardless of whether or not `to_owned()` has been called, the key must hash the same way.
|
pub fn entry<'a>(&'a mut self, key: K) -> Entry<'a, K, V>
|
||||||
pub fn entry<'a, Q: ?Sized>(&'a mut self, key: &'a Q) -> Entry<'a, Q, K, V>
|
|
||||||
where Q: Eq + Hash<S> + ToOwned<K>
|
|
||||||
{
|
{
|
||||||
// Gotta resize now.
|
// Gotta resize now.
|
||||||
self.reserve(1);
|
self.reserve(1);
|
||||||
|
|
||||||
let hash = self.make_hash(key);
|
let hash = self.make_hash(&key);
|
||||||
search_entry_hashed(&mut self.table, hash, key)
|
search_entry_hashed(&mut self.table, hash, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1142,9 +1140,8 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn search_entry_hashed<'a, K, V, Q: ?Sized>(table: &'a mut RawTable<K,V>, hash: SafeHash, k: &'a Q)
|
fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable<K,V>, hash: SafeHash, k: K)
|
||||||
-> Entry<'a, Q, K, V>
|
-> Entry<'a, K, V>
|
||||||
where Q: Eq + ToOwned<K>
|
|
||||||
{
|
{
|
||||||
// Worst case, we'll find one empty bucket among `size + 1` buckets.
|
// Worst case, we'll find one empty bucket among `size + 1` buckets.
|
||||||
let size = table.size();
|
let size = table.size();
|
||||||
@@ -1167,7 +1164,7 @@ fn search_entry_hashed<'a, K, V, Q: ?Sized>(table: &'a mut RawTable<K,V>, hash:
|
|||||||
// hash matches?
|
// hash matches?
|
||||||
if bucket.hash() == hash {
|
if bucket.hash() == hash {
|
||||||
// key matches?
|
// key matches?
|
||||||
if *k == *BorrowFrom::borrow_from(bucket.read().0) {
|
if k == *bucket.read().0 {
|
||||||
return Occupied(OccupiedEntry{
|
return Occupied(OccupiedEntry{
|
||||||
elem: bucket,
|
elem: bucket,
|
||||||
});
|
});
|
||||||
@@ -1331,19 +1328,19 @@ pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
|
|||||||
|
|
||||||
#[stable]
|
#[stable]
|
||||||
/// A view into a single empty location in a HashMap
|
/// A view into a single empty location in a HashMap
|
||||||
pub struct VacantEntry<'a, Q: ?Sized + 'a, K: 'a, V: 'a> {
|
pub struct VacantEntry<'a, K: 'a, V: 'a> {
|
||||||
hash: SafeHash,
|
hash: SafeHash,
|
||||||
key: &'a Q,
|
key: K,
|
||||||
elem: VacantEntryState<K, V, &'a mut RawTable<K, V>>,
|
elem: VacantEntryState<K, V, &'a mut RawTable<K, V>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable]
|
#[stable]
|
||||||
/// A view into a single location in a map, which may be vacant or occupied
|
/// A view into a single location in a map, which may be vacant or occupied
|
||||||
pub enum Entry<'a, Q: ?Sized + 'a, K: 'a, V: 'a> {
|
pub enum Entry<'a, K: 'a, V: 'a> {
|
||||||
/// An occupied Entry
|
/// An occupied Entry
|
||||||
Occupied(OccupiedEntry<'a, K, V>),
|
Occupied(OccupiedEntry<'a, K, V>),
|
||||||
/// A vacant Entry
|
/// A vacant Entry
|
||||||
Vacant(VacantEntry<'a, Q, K, V>),
|
Vacant(VacantEntry<'a, K, V>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Possible states of a VacantEntry
|
/// Possible states of a VacantEntry
|
||||||
@@ -1409,10 +1406,10 @@ impl<'a, K: 'a, V: 'a> Iterator for Drain<'a, K, V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Q: ?Sized, K, V> Entry<'a, Q, K, V> {
|
impl<'a, K, V> Entry<'a, K, V> {
|
||||||
#[unstable = "matches collection reform v2 specification, waiting for dust to settle"]
|
#[unstable = "matches collection reform v2 specification, waiting for dust to settle"]
|
||||||
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
|
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
|
||||||
pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, Q, K, V>> {
|
pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, K, V>> {
|
||||||
match self {
|
match self {
|
||||||
Occupied(entry) => Ok(entry.into_mut()),
|
Occupied(entry) => Ok(entry.into_mut()),
|
||||||
Vacant(entry) => Err(entry),
|
Vacant(entry) => Err(entry),
|
||||||
@@ -1455,17 +1452,17 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Q: ?Sized + 'a + ToOwned<K>, K: 'a, V: 'a> VacantEntry<'a, Q, K, V> {
|
impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
|
||||||
#[stable]
|
#[stable]
|
||||||
/// Sets the value of the entry with the VacantEntry's key,
|
/// Sets the value of the entry with the VacantEntry's key,
|
||||||
/// and returns a mutable reference to it
|
/// and returns a mutable reference to it
|
||||||
pub fn insert(self, value: V) -> &'a mut V {
|
pub fn insert(self, value: V) -> &'a mut V {
|
||||||
match self.elem {
|
match self.elem {
|
||||||
NeqElem(bucket, ib) => {
|
NeqElem(bucket, ib) => {
|
||||||
robin_hood(bucket, ib, self.hash, self.key.to_owned(), value)
|
robin_hood(bucket, ib, self.hash, self.key, value)
|
||||||
}
|
}
|
||||||
NoElem(bucket) => {
|
NoElem(bucket) => {
|
||||||
bucket.put(self.hash, self.key.to_owned(), value).into_mut_refs().1
|
bucket.put(self.hash, self.key, value).into_mut_refs().1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1497,8 +1494,6 @@ mod test_map {
|
|||||||
use super::HashMap;
|
use super::HashMap;
|
||||||
use super::Entry::{Occupied, Vacant};
|
use super::Entry::{Occupied, Vacant};
|
||||||
use iter::{range_inclusive, range_step_inclusive, repeat};
|
use iter::{range_inclusive, range_step_inclusive, repeat};
|
||||||
use borrow::ToOwned;
|
|
||||||
use hash;
|
|
||||||
use cell::RefCell;
|
use cell::RefCell;
|
||||||
use rand::{weak_rng, Rng};
|
use rand::{weak_rng, Rng};
|
||||||
|
|
||||||
@@ -2092,7 +2087,7 @@ mod test_map {
|
|||||||
let mut map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
|
let mut map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
|
||||||
|
|
||||||
// Existing key (insert)
|
// Existing key (insert)
|
||||||
match map.entry(&1) {
|
match map.entry(1) {
|
||||||
Vacant(_) => unreachable!(),
|
Vacant(_) => unreachable!(),
|
||||||
Occupied(mut view) => {
|
Occupied(mut view) => {
|
||||||
assert_eq!(view.get(), &10);
|
assert_eq!(view.get(), &10);
|
||||||
@@ -2104,7 +2099,7 @@ mod test_map {
|
|||||||
|
|
||||||
|
|
||||||
// Existing key (update)
|
// Existing key (update)
|
||||||
match map.entry(&2) {
|
match map.entry(2) {
|
||||||
Vacant(_) => unreachable!(),
|
Vacant(_) => unreachable!(),
|
||||||
Occupied(mut view) => {
|
Occupied(mut view) => {
|
||||||
let v = view.get_mut();
|
let v = view.get_mut();
|
||||||
@@ -2116,7 +2111,7 @@ mod test_map {
|
|||||||
assert_eq!(map.len(), 6);
|
assert_eq!(map.len(), 6);
|
||||||
|
|
||||||
// Existing key (take)
|
// Existing key (take)
|
||||||
match map.entry(&3) {
|
match map.entry(3) {
|
||||||
Vacant(_) => unreachable!(),
|
Vacant(_) => unreachable!(),
|
||||||
Occupied(view) => {
|
Occupied(view) => {
|
||||||
assert_eq!(view.remove(), 30);
|
assert_eq!(view.remove(), 30);
|
||||||
@@ -2127,7 +2122,7 @@ mod test_map {
|
|||||||
|
|
||||||
|
|
||||||
// Inexistent key (insert)
|
// Inexistent key (insert)
|
||||||
match map.entry(&10) {
|
match map.entry(10) {
|
||||||
Occupied(_) => unreachable!(),
|
Occupied(_) => unreachable!(),
|
||||||
Vacant(view) => {
|
Vacant(view) => {
|
||||||
assert_eq!(*view.insert(1000), 1000);
|
assert_eq!(*view.insert(1000), 1000);
|
||||||
@@ -2158,7 +2153,7 @@ mod test_map {
|
|||||||
|
|
||||||
for i in range(0u, 1000) {
|
for i in range(0u, 1000) {
|
||||||
let x = rng.gen_range(-10, 10);
|
let x = rng.gen_range(-10, 10);
|
||||||
match m.entry(&x) {
|
match m.entry(x) {
|
||||||
Vacant(_) => {},
|
Vacant(_) => {},
|
||||||
Occupied(e) => {
|
Occupied(e) => {
|
||||||
println!("{}: remove {}", i, x);
|
println!("{}: remove {}", i, x);
|
||||||
|
|||||||
@@ -255,7 +255,7 @@
|
|||||||
//! let message = "she sells sea shells by the sea shore";
|
//! let message = "she sells sea shells by the sea shore";
|
||||||
//!
|
//!
|
||||||
//! for c in message.chars() {
|
//! for c in message.chars() {
|
||||||
//! match count.entry(&c) {
|
//! match count.entry(c) {
|
||||||
//! Vacant(entry) => { entry.insert(1u); },
|
//! Vacant(entry) => { entry.insert(1u); },
|
||||||
//! Occupied(mut entry) => *entry.get_mut() += 1,
|
//! Occupied(mut entry) => *entry.get_mut() += 1,
|
||||||
//! }
|
//! }
|
||||||
@@ -290,7 +290,7 @@
|
|||||||
//! for id in orders.into_iter() {
|
//! for id in orders.into_iter() {
|
||||||
//! // If this is the first time we've seen this customer, initialize them
|
//! // If this is the first time we've seen this customer, initialize them
|
||||||
//! // with no blood alcohol. Otherwise, just retrieve them.
|
//! // with no blood alcohol. Otherwise, just retrieve them.
|
||||||
//! let person = match blood_alcohol.entry(&id) {
|
//! let person = match blood_alcohol.entry(id) {
|
||||||
//! Vacant(entry) => entry.insert(Person{id: id, blood_alcohol: 0.0}),
|
//! Vacant(entry) => entry.insert(Person{id: id, blood_alcohol: 0.0}),
|
||||||
//! Occupied(entry) => entry.into_mut(),
|
//! Occupied(entry) => entry.into_mut(),
|
||||||
//! };
|
//! };
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ pub fn apply_mark(m: Mrk, ctxt: SyntaxContext) -> SyntaxContext {
|
|||||||
/// Extend a syntax context with a given mark and sctable (explicit memoization)
|
/// Extend a syntax context with a given mark and sctable (explicit memoization)
|
||||||
fn apply_mark_internal(m: Mrk, ctxt: SyntaxContext, table: &SCTable) -> SyntaxContext {
|
fn apply_mark_internal(m: Mrk, ctxt: SyntaxContext, table: &SCTable) -> SyntaxContext {
|
||||||
let key = (ctxt, m);
|
let key = (ctxt, m);
|
||||||
* table.mark_memo.borrow_mut().entry(&key).get().unwrap_or_else(
|
* table.mark_memo.borrow_mut().entry(key).get().unwrap_or_else(
|
||||||
|vacant_entry|
|
|vacant_entry|
|
||||||
vacant_entry.insert(idx_push(&mut *table.table.borrow_mut(), Mark(m, ctxt))))
|
vacant_entry.insert(idx_push(&mut *table.table.borrow_mut(), Mark(m, ctxt))))
|
||||||
}
|
}
|
||||||
@@ -84,7 +84,7 @@ fn apply_rename_internal(id: Ident,
|
|||||||
table: &SCTable) -> SyntaxContext {
|
table: &SCTable) -> SyntaxContext {
|
||||||
let key = (ctxt, id, to);
|
let key = (ctxt, id, to);
|
||||||
|
|
||||||
* table.rename_memo.borrow_mut().entry(&key).get().unwrap_or_else(
|
* table.rename_memo.borrow_mut().entry(key).get().unwrap_or_else(
|
||||||
|vacant_entry|
|
|vacant_entry|
|
||||||
vacant_entry.insert(idx_push(&mut *table.table.borrow_mut(), Rename(id, to, ctxt))))
|
vacant_entry.insert(idx_push(&mut *table.table.borrow_mut(), Rename(id, to, ctxt))))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc<NamedMatch>])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
&TtToken(sp, MatchNt(bind_name, _, _, _)) => {
|
&TtToken(sp, MatchNt(bind_name, _, _, _)) => {
|
||||||
match ret_val.entry(&bind_name) {
|
match ret_val.entry(bind_name) {
|
||||||
Vacant(spot) => {
|
Vacant(spot) => {
|
||||||
spot.insert(res[*idx].clone());
|
spot.insert(res[*idx].clone());
|
||||||
*idx += 1;
|
*idx += 1;
|
||||||
|
|||||||
@@ -444,7 +444,7 @@ pub fn freq_count<T, U>(mut iter: T) -> hash_map::HashMap<U, uint>
|
|||||||
{
|
{
|
||||||
let mut map: hash_map::HashMap<U,uint> = hash_map::HashMap::new();
|
let mut map: hash_map::HashMap<U,uint> = hash_map::HashMap::new();
|
||||||
for elem in iter {
|
for elem in iter {
|
||||||
match map.entry(&elem) {
|
match map.entry(elem) {
|
||||||
Occupied(mut entry) => { *entry.get_mut() += 1; },
|
Occupied(mut entry) => { *entry.get_mut() += 1; },
|
||||||
Vacant(entry) => { entry.insert(1); },
|
Vacant(entry) => { entry.insert(1); },
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user