Auto merge of #44734 - mchlrhw:wip/hashmap-entry-and-then, r=BurntSushi

Implement `and_modify` on `Entry`

## Motivation

`Entry`s are useful for allowing access to existing values in a map while also allowing default values to be inserted for absent keys. The existing API is similar to that of `Option`, where `or` and `or_with` can be used if the option variant is `None`.

The `Entry` API is, however, missing an equivalent of `Option`'s `and_then` method. If it were present it would be possible to modify an existing entry before calling `or_insert` without resorting to matching on the entry variant.

Tracking issue: https://github.com/rust-lang/rust/issues/44733.
This commit is contained in:
bors
2017-10-06 12:51:11 +00:00
3 changed files with 146 additions and 0 deletions

View File

@@ -2102,6 +2102,40 @@ impl<'a, K: Ord, V> Entry<'a, K, V> {
Vacant(ref entry) => entry.key(),
}
}
/// Provides in-place mutable access to an occupied entry before any
/// potential inserts into the map.
///
/// # Examples
///
/// ```
/// #![feature(entry_and_modify)]
/// use std::collections::BTreeMap;
///
/// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
///
/// map.entry("poneyland")
/// .and_modify(|e| { *e += 1 })
/// .or_insert(42);
/// assert_eq!(map["poneyland"], 42);
///
/// map.entry("poneyland")
/// .and_modify(|e| { *e += 1 })
/// .or_insert(42);
/// assert_eq!(map["poneyland"], 43);
/// ```
#[unstable(feature = "entry_and_modify", issue = "44733")]
pub fn and_modify<F>(self, mut f: F) -> Self
where F: FnMut(&mut V)
{
match self {
Occupied(mut entry) => {
f(entry.get_mut());
Occupied(entry)
},
Vacant(entry) => Vacant(entry),
}
}
}
impl<'a, K: Ord, V: Default> Entry<'a, K, V> {