Skip to content

Commit

Permalink
Auto merge of #22930 - Gankro:entry_3, r=aturon
Browse files Browse the repository at this point in the history
RFC pending, but this is the patch that does it.

Totally untested. Likely needs some removed imports. std::collections docs should also be updated to provide better examples.

Closes #23508
  • Loading branch information
bors committed Mar 27, 2015
2 parents 199bdcf + 1132198 commit 64a4e01
Show file tree
Hide file tree
Showing 14 changed files with 102 additions and 91 deletions.
39 changes: 27 additions & 12 deletions src/libcollections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1143,15 +1143,39 @@ impl<'a, K, V> DoubleEndedIterator for RangeMut<'a, K, V> {
}

impl<'a, K: Ord, V> Entry<'a, K, V> {
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
#[unstable(feature = "std_misc",
reason = "will soon be replaced by or_insert")]
#[deprecated(since = "1.0",
reason = "replaced with more ergonomic `or_insert` and `or_insert_with`")]
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, K, 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.
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.
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()),
}
}
}

impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
Expand Down Expand Up @@ -1563,21 +1587,12 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// ```
/// # #![feature(collections)]
/// use std::collections::BTreeMap;
/// use std::collections::btree_map::Entry;
///
/// let mut count: BTreeMap<&str, usize> = BTreeMap::new();
///
/// // count the number of occurrences of letters in the vec
/// for x in vec!["a","b","a","c","a","b"].iter() {
/// match count.entry(*x) {
/// Entry::Vacant(view) => {
/// view.insert(1);
/// },
/// Entry::Occupied(mut view) => {
/// let v = view.get_mut();
/// *v += 1;
/// },
/// }
/// for x in vec!["a","b","a","c","a","b"] {
/// *count.entry(x).or_insert(0) += 1;
/// }
///
/// assert_eq!(count["a"], 3);
Expand Down
37 changes: 26 additions & 11 deletions src/libcollections/vec_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -632,21 +632,12 @@ impl<V> VecMap<V> {
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
/// use std::collections::vec_map::Entry;
///
/// 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].iter() {
/// match count.entry(*x) {
/// Entry::Vacant(view) => {
/// view.insert(1);
/// },
/// Entry::Occupied(mut view) => {
/// let v = view.get_mut();
/// *v += 1;
/// },
/// }
/// for x in vec![1, 2, 1, 2, 3, 4, 1, 2, 4] {
/// *count.entry(x).or_insert(0) += 1;
/// }
///
/// assert_eq!(count[1], 3);
Expand Down Expand Up @@ -675,13 +666,37 @@ impl<V> VecMap<V> {
impl<'a, V> Entry<'a, V> {
#[unstable(feature = "collections",
reason = "will soon be replaced by or_insert")]
#[deprecated(since = "1.0",
reason = "replaced with more ergonomic `or_insert` and `or_insert_with`")]
/// 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.
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.
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()),
}
}
}

impl<'a, V> VacantEntry<'a, V> {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/metadata/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,8 @@ impl<'a> Context<'a> {
info!("lib candidate: {}", path.display());

let hash_str = hash.to_string();
let slot = candidates.entry(hash_str).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert((HashMap::new(), HashMap::new())));
let slot = candidates.entry(hash_str)
.or_insert_with(|| (HashMap::new(), HashMap::new()));
let (ref mut rlibs, ref mut dylibs) = *slot;
if rlib {
rlibs.insert(fs::realpath(path).unwrap(), kind);
Expand Down
14 changes: 2 additions & 12 deletions src/librustc/middle/dataflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,7 @@ fn build_nodeid_to_index(decl: Option<&ast::FnDecl>,

cfg.graph.each_node(|node_idx, node| {
if let cfg::CFGNodeData::AST(id) = node.data {
match index.entry(id).get() {
Ok(v) => v.push(node_idx),
Err(e) => {
e.insert(vec![node_idx]);
}
}
index.entry(id).or_insert(vec![]).push(node_idx);
}
true
});
Expand All @@ -185,12 +180,7 @@ fn build_nodeid_to_index(decl: Option<&ast::FnDecl>,
visit::walk_fn_decl(&mut formals, decl);
impl<'a, 'v> visit::Visitor<'v> for Formals<'a> {
fn visit_pat(&mut self, p: &ast::Pat) {
match self.index.entry(p.id).get() {
Ok(v) => v.push(self.entry),
Err(e) => {
e.insert(vec![self.entry]);
}
}
self.index.entry(p.id).or_insert(vec![]).push(self.entry);
visit::walk_pat(self, p)
}
}
Expand Down
7 changes: 2 additions & 5 deletions src/librustc/middle/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
use middle::infer::{InferCtxt};
use middle::ty::{self, RegionEscape, Ty};
use std::collections::HashSet;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::default::Default;
use syntax::ast;
use util::common::ErrorReported;
Expand Down Expand Up @@ -437,9 +436,7 @@ fn register_region_obligation<'tcx>(tcx: &ty::ctxt<'tcx>,
debug!("register_region_obligation({})",
region_obligation.repr(tcx));

match region_obligations.entry(region_obligation.cause.body_id) {
Vacant(entry) => { entry.insert(vec![region_obligation]); },
Occupied(mut entry) => { entry.get_mut().push(region_obligation); },
}
region_obligations.entry(region_obligation.cause.body_id).or_insert(vec![])
.push(region_obligation);

}
8 changes: 2 additions & 6 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5669,9 +5669,7 @@ pub fn lookup_field_type<'tcx>(tcx: &ctxt<'tcx>,
node_id_to_type(tcx, id.node)
} else {
let mut tcache = tcx.tcache.borrow_mut();
let pty = tcache.entry(id).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert(csearch::get_field_type(tcx, struct_id, id)));
pty.ty
tcache.entry(id).or_insert_with(|| csearch::get_field_type(tcx, struct_id, id)).ty
};
ty.subst(tcx, substs)
}
Expand Down Expand Up @@ -6819,9 +6817,7 @@ pub fn replace_late_bound_regions<'tcx, T, F>(
debug!("region={}", region.repr(tcx));
match region {
ty::ReLateBound(debruijn, br) if debruijn.depth == current_depth => {
let region =
* map.entry(br).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert(mapf(br)));
let region = *map.entry(br).or_insert_with(|| mapf(br));

if let ty::ReLateBound(debruijn1, br) = region {
// If the callback returns a late-bound region,
Expand Down
6 changes: 1 addition & 5 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ use syntax::parse::token::InternedString;

use getopts;
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::env;
use std::fmt;
use std::path::PathBuf;
Expand Down Expand Up @@ -1037,10 +1036,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
None => early_error("--extern value must be of the format `foo=bar`"),
};

match externs.entry(name.to_string()) {
Vacant(entry) => { entry.insert(vec![location.to_string()]); },
Occupied(mut entry) => { entry.get_mut().push(location.to_string()); },
}
externs.entry(name.to_string()).or_insert(vec![]).push(location.to_string());
}

let crate_name = matches.opt_str("crate-name");
Expand Down
7 changes: 2 additions & 5 deletions src/librustc_resolve/resolve_imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -836,11 +836,8 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
let is_public = import_directive.is_public;

let mut import_resolutions = module_.import_resolutions.borrow_mut();
let dest_import_resolution = import_resolutions.entry(name).get().unwrap_or_else(
|vacant_entry| {
// Create a new import resolution from this child.
vacant_entry.insert(ImportResolution::new(id, is_public))
});
let dest_import_resolution = import_resolutions.entry(name)
.or_insert_with(|| ImportResolution::new(id, is_public));

debug!("(resolving glob import) writing resolution `{}` in `{}` \
to `{}`",
Expand Down
7 changes: 1 addition & 6 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
use util::lev_distance::lev_distance;

use std::cell::{Cell, Ref, RefCell};
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::mem::replace;
use std::rc::Rc;
use std::iter::repeat;
Expand Down Expand Up @@ -1362,11 +1361,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
closure_def_id: ast::DefId,
r: DeferredCallResolutionHandler<'tcx>) {
let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
let mut vec = match deferred_call_resolutions.entry(closure_def_id) {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.insert(Vec::new()),
};
vec.push(r);
deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
}

fn remove_deferred_call_resolutions(&self,
Expand Down
13 changes: 4 additions & 9 deletions src/librustdoc/html/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -876,9 +876,7 @@ impl DocFolder for Cache {
if let clean::ImplItem(ref i) = item.inner {
match i.trait_ {
Some(clean::ResolvedPath{ did, .. }) => {
let v = self.implementors.entry(did).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
v.push(Implementor {
self.implementors.entry(did).or_insert(vec![]).push(Implementor {
def_id: item.def_id,
generics: i.generics.clone(),
trait_: i.trait_.as_ref().unwrap().clone(),
Expand Down Expand Up @@ -1080,9 +1078,7 @@ impl DocFolder for Cache {
};

if let Some(did) = did {
let v = self.impls.entry(did).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
v.push(Impl {
self.impls.entry(did).or_insert(vec![]).push(Impl {
impl_: i,
dox: dox,
stability: item.stability.clone(),
Expand Down Expand Up @@ -1334,9 +1330,8 @@ impl Context {
Some(ref s) => s.to_string(),
};
let short = short.to_string();
let v = map.entry(short).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
v.push((myname, Some(plain_summary_line(item.doc_value()))));
map.entry(short).or_insert(vec![])
.push((myname, Some(plain_summary_line(item.doc_value()))));
}

for (_, items) in &mut map {
Expand Down
4 changes: 1 addition & 3 deletions src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,9 +352,7 @@ fn parse_externs(matches: &getopts::Matches) -> Result<core::Externs, String> {
}
};
let name = name.to_string();
let locs = externs.entry(name).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
locs.push(location.to_string());
externs.entry(name).or_insert(vec![]).push(location.to_string());
}
Ok(externs)
}
Expand Down
27 changes: 26 additions & 1 deletion src/libstd/collections/hash/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use hash::{Hash, SipHasher};
use iter::{self, Iterator, ExactSizeIterator, IntoIterator, IteratorExt, FromIterator, Extend, Map};
use marker::Sized;
use mem::{self, replace};
use ops::{Deref, FnMut, Index};
use ops::{Deref, FnMut, FnOnce, Index};
use option::Option::{self, Some, None};
use rand::{self, Rng};
use result::Result::{self, Ok, Err};
Expand Down Expand Up @@ -1488,12 +1488,37 @@ impl<'a, K, V> Entry<'a, K, V> {
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant.
#[unstable(feature = "std_misc",
reason = "will soon be replaced by or_insert")]
#[deprecated(since = "1.0",
reason = "replaced with more ergonomic `or_insert` and `or_insert_with`")]
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, K, 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.
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.
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()),
}
}
}

impl<'a, K, V> OccupiedEntry<'a, K, V> {
Expand Down
10 changes: 2 additions & 8 deletions src/libstd/collections/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,10 +307,7 @@
//! let message = "she sells sea shells by the sea shore";
//!
//! for c in message.chars() {
//! match count.entry(c) {
//! Entry::Vacant(entry) => { entry.insert(1); },
//! Entry::Occupied(mut entry) => *entry.get_mut() += 1,
//! }
//! *count.entry(c).or_insert(0) += 1;
//! }
//!
//! assert_eq!(count.get(&'s'), Some(&8));
Expand Down Expand Up @@ -343,10 +340,7 @@
//! for id in orders.into_iter() {
//! // If this is the first time we've seen this customer, initialize them
//! // with no blood alcohol. Otherwise, just retrieve them.
//! let person = match blood_alcohol.entry(id) {
//! Entry::Vacant(entry) => entry.insert(Person{id: id, blood_alcohol: 0.0}),
//! Entry::Occupied(entry) => entry.into_mut(),
//! };
//! let person = blood_alcohol.entry(id).or_insert(Person{id: id, blood_alcohol: 0.0});
//!
//! // Reduce their blood alcohol level. It takes time to order and drink a beer!
//! person.blood_alcohol *= 0.9;
Expand Down
Loading

0 comments on commit 64a4e01

Please sign in to comment.