mirror of
https://github.com/openharmony/third_party_rust_hashbrown.git
synced 2026-07-01 21:04:01 -04:00
Merge branch 'rust-lang:master' into update_hashbrown_doc_2
This commit is contained in:
+335
-19
@@ -300,6 +300,8 @@ impl<K, V> HashMap<K, V, DefaultHashBuilder> {
|
||||
/// ```
|
||||
/// use hashbrown::HashMap;
|
||||
/// let mut map: HashMap<&str, i32> = HashMap::new();
|
||||
/// assert_eq!(map.len(), 0);
|
||||
/// assert_eq!(map.capacity(), 0);
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub fn new() -> Self {
|
||||
@@ -316,6 +318,8 @@ impl<K, V> HashMap<K, V, DefaultHashBuilder> {
|
||||
/// ```
|
||||
/// use hashbrown::HashMap;
|
||||
/// let mut map: HashMap<&str, i32> = HashMap::with_capacity(10);
|
||||
/// assert_eq!(map.len(), 0);
|
||||
/// assert!(map.capacity() >= 10);
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub fn with_capacity(capacity: usize) -> Self {
|
||||
@@ -348,7 +352,8 @@ impl<K, V, S> HashMap<K, V, S> {
|
||||
/// Creates an empty `HashMap` which will use the given hash builder to hash
|
||||
/// keys.
|
||||
///
|
||||
/// The created map has the default initial capacity.
|
||||
/// The hash map is initially created with a capacity of 0, so it will not
|
||||
/// allocate until it is first inserted into.
|
||||
///
|
||||
/// Warning: `hash_builder` is normally randomly generated, and
|
||||
/// is designed to allow HashMaps to be resistant to attacks that
|
||||
@@ -366,10 +371,13 @@ impl<K, V, S> HashMap<K, V, S> {
|
||||
///
|
||||
/// let s = DefaultHashBuilder::default();
|
||||
/// let mut map = HashMap::with_hasher(s);
|
||||
/// assert_eq!(map.len(), 0);
|
||||
/// assert_eq!(map.capacity(), 0);
|
||||
///
|
||||
/// map.insert(1, 2);
|
||||
/// ```
|
||||
///
|
||||
/// [`BuildHasher`]: ../../std/hash/trait.BuildHasher.html
|
||||
/// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub const fn with_hasher(hash_builder: S) -> Self {
|
||||
Self {
|
||||
@@ -400,10 +408,13 @@ impl<K, V, S> HashMap<K, V, S> {
|
||||
///
|
||||
/// let s = DefaultHashBuilder::default();
|
||||
/// let mut map = HashMap::with_capacity_and_hasher(10, s);
|
||||
/// assert_eq!(map.len(), 0);
|
||||
/// assert!(map.capacity() >= 10);
|
||||
///
|
||||
/// map.insert(1, 2);
|
||||
/// ```
|
||||
///
|
||||
/// [`BuildHasher`]: ../../std/hash/trait.BuildHasher.html
|
||||
/// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
|
||||
Self {
|
||||
@@ -506,6 +517,7 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
|
||||
/// ```
|
||||
/// use hashbrown::HashMap;
|
||||
/// let map: HashMap<i32, i32> = HashMap::with_capacity(100);
|
||||
/// assert_eq!(map.len(), 0);
|
||||
/// assert!(map.capacity() >= 100);
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
@@ -525,10 +537,20 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
|
||||
/// map.insert("a", 1);
|
||||
/// map.insert("b", 2);
|
||||
/// map.insert("c", 3);
|
||||
/// assert_eq!(map.len(), 3);
|
||||
/// let mut vec: Vec<&str> = Vec::new();
|
||||
///
|
||||
/// for key in map.keys() {
|
||||
/// println!("{}", key);
|
||||
/// vec.push(*key);
|
||||
/// }
|
||||
///
|
||||
/// // The `Keys` iterator produces keys in arbitrary order, so the
|
||||
/// // keys must be sorted to test them against a sorted array.
|
||||
/// vec.sort_unstable();
|
||||
/// assert_eq!(vec, ["a", "b", "c"]);
|
||||
///
|
||||
/// assert_eq!(map.len(), 3);
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub fn keys(&self) -> Keys<'_, K, V> {
|
||||
@@ -547,10 +569,20 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
|
||||
/// map.insert("a", 1);
|
||||
/// map.insert("b", 2);
|
||||
/// map.insert("c", 3);
|
||||
/// assert_eq!(map.len(), 3);
|
||||
/// let mut vec: Vec<i32> = Vec::new();
|
||||
///
|
||||
/// for val in map.values() {
|
||||
/// println!("{}", val);
|
||||
/// vec.push(*val);
|
||||
/// }
|
||||
///
|
||||
/// // The `Values` iterator produces values in arbitrary order, so the
|
||||
/// // values must be sorted to test them against a sorted array.
|
||||
/// vec.sort_unstable();
|
||||
/// assert_eq!(vec, [1, 2, 3]);
|
||||
///
|
||||
/// assert_eq!(map.len(), 3);
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub fn values(&self) -> Values<'_, K, V> {
|
||||
@@ -575,9 +607,20 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
|
||||
/// *val = *val + 10;
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(map.len(), 3);
|
||||
/// let mut vec: Vec<i32> = Vec::new();
|
||||
///
|
||||
/// for val in map.values() {
|
||||
/// println!("{}", val);
|
||||
/// vec.push(*val);
|
||||
/// }
|
||||
///
|
||||
/// // The `Values` iterator produces values in arbitrary order, so the
|
||||
/// // values must be sorted to test them against a sorted array.
|
||||
/// vec.sort_unstable();
|
||||
/// assert_eq!(vec, [11, 12, 13]);
|
||||
///
|
||||
/// assert_eq!(map.len(), 3);
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
|
||||
@@ -598,10 +641,20 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
|
||||
/// map.insert("a", 1);
|
||||
/// map.insert("b", 2);
|
||||
/// map.insert("c", 3);
|
||||
/// assert_eq!(map.len(), 3);
|
||||
/// let mut vec: Vec<(&str, i32)> = Vec::new();
|
||||
///
|
||||
/// for (key, val) in map.iter() {
|
||||
/// println!("key: {} val: {}", key, val);
|
||||
/// vec.push((*key, *val));
|
||||
/// }
|
||||
///
|
||||
/// // The `Iter` iterator produces items in arbitrary order, so the
|
||||
/// // items must be sorted to test them against a sorted array.
|
||||
/// vec.sort_unstable();
|
||||
/// assert_eq!(vec, [("a", 1), ("b", 2), ("c", 3)]);
|
||||
///
|
||||
/// assert_eq!(map.len(), 3);
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub fn iter(&self) -> Iter<'_, K, V> {
|
||||
@@ -633,9 +686,20 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
|
||||
/// *val *= 2;
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(map.len(), 3);
|
||||
/// let mut vec: Vec<(&str, i32)> = Vec::new();
|
||||
///
|
||||
/// for (key, val) in &map {
|
||||
/// println!("key: {} val: {}", key, val);
|
||||
/// vec.push((*key, *val));
|
||||
/// }
|
||||
///
|
||||
/// // The `Iter` iterator produces items in arbitrary order, so the
|
||||
/// // items must be sorted to test them against a sorted array.
|
||||
/// vec.sort_unstable();
|
||||
/// assert_eq!(vec, [("a", 2), ("b", 4), ("c", 6)]);
|
||||
///
|
||||
/// assert_eq!(map.len(), 3);
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
|
||||
@@ -691,6 +755,10 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
|
||||
/// Clears the map, returning all key-value pairs as an iterator. Keeps the
|
||||
/// allocated memory for reuse.
|
||||
///
|
||||
/// If the returned iterator is dropped before being fully consumed, it
|
||||
/// drops the remaining key-value pairs. The returned iterator keeps a
|
||||
/// mutable borrow on the vector to optimize its implementation.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
@@ -699,12 +767,27 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
|
||||
/// let mut a = HashMap::new();
|
||||
/// a.insert(1, "a");
|
||||
/// a.insert(2, "b");
|
||||
/// let capacity_before_drain = a.capacity();
|
||||
///
|
||||
/// for (k, v) in a.drain().take(1) {
|
||||
/// assert!(k == 1 || k == 2);
|
||||
/// assert!(v == "a" || v == "b");
|
||||
/// }
|
||||
///
|
||||
/// // As we can see, the map is empty and contains no element.
|
||||
/// assert!(a.is_empty() && a.len() == 0);
|
||||
/// // But map capacity is equal to old one.
|
||||
/// assert_eq!(a.capacity(), capacity_before_drain);
|
||||
///
|
||||
/// let mut a = HashMap::new();
|
||||
/// a.insert(1, "a");
|
||||
/// a.insert(2, "b");
|
||||
///
|
||||
/// { // Iterator is dropped without being consumed.
|
||||
/// let d = a.drain();
|
||||
/// }
|
||||
///
|
||||
/// // But the map is empty even if we do not use Drain iterator.
|
||||
/// assert!(a.is_empty());
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
@@ -714,9 +797,11 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Retains only the elements specified by the predicate.
|
||||
/// Retains only the elements specified by the predicate. Keeps the
|
||||
/// allocated memory for reuse.
|
||||
///
|
||||
/// In other words, remove all pairs `(k, v)` such that `f(&k,&mut v)` returns `false`.
|
||||
/// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.
|
||||
/// The elements are visited in unsorted (and unspecified) order.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@@ -724,8 +809,19 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
|
||||
/// use hashbrown::HashMap;
|
||||
///
|
||||
/// let mut map: HashMap<i32, i32> = (0..8).map(|x|(x, x*10)).collect();
|
||||
/// assert_eq!(map.len(), 8);
|
||||
/// let capacity_before_retain = map.capacity();
|
||||
///
|
||||
/// map.retain(|&k, _| k % 2 == 0);
|
||||
///
|
||||
/// // We can see, that the number of elements inside map is changed.
|
||||
/// assert_eq!(map.len(), 4);
|
||||
/// // But map capacity is equal to old one.
|
||||
/// assert_eq!(map.capacity(), capacity_before_retain);
|
||||
///
|
||||
/// let mut vec: Vec<(i32, i32)> = map.iter().map(|(&k, &v)| (k, v)).collect();
|
||||
/// vec.sort_unstable();
|
||||
/// assert_eq!(vec, [(0, 0), (2, 20), (4, 40), (6, 60)]);
|
||||
/// ```
|
||||
pub fn retain<F>(&mut self, mut f: F)
|
||||
where
|
||||
@@ -745,18 +841,28 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
|
||||
/// Drains elements which are true under the given predicate,
|
||||
/// and returns an iterator over the removed items.
|
||||
///
|
||||
/// In other words, move all pairs `(k, v)` such that `f(&k,&mut v)` returns `true` out
|
||||
/// In other words, move all pairs `(k, v)` such that `f(&k, &mut v)` returns `true` out
|
||||
/// into another iterator.
|
||||
///
|
||||
/// Note that `drain_filter` lets you mutate every value in the filter closure, regardless of
|
||||
/// whether you choose to keep or remove it.
|
||||
///
|
||||
/// When the returned DrainedFilter is dropped, any remaining elements that satisfy
|
||||
/// the predicate are dropped from the table.
|
||||
///
|
||||
/// It is unspecified how many more elements will be subjected to the closure
|
||||
/// if a panic occurs in the closure, or a panic occurs while dropping an element,
|
||||
/// or if the `DrainFilter` value is leaked.
|
||||
///
|
||||
/// Keeps the allocated memory for reuse.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use hashbrown::HashMap;
|
||||
///
|
||||
/// let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x)).collect();
|
||||
/// let capacity_before_drain_filter = map.capacity();
|
||||
/// let drained: HashMap<i32, i32> = map.drain_filter(|k, _v| k % 2 == 0).collect();
|
||||
///
|
||||
/// let mut evens = drained.keys().cloned().collect::<Vec<_>>();
|
||||
@@ -766,6 +872,18 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
|
||||
///
|
||||
/// assert_eq!(evens, vec![0, 2, 4, 6]);
|
||||
/// assert_eq!(odds, vec![1, 3, 5, 7]);
|
||||
/// // Map capacity is equal to old one.
|
||||
/// assert_eq!(map.capacity(), capacity_before_drain_filter);
|
||||
///
|
||||
/// let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x)).collect();
|
||||
///
|
||||
/// { // Iterator is dropped without being consumed.
|
||||
/// let d = map.drain_filter(|k, _v| k % 2 != 0);
|
||||
/// }
|
||||
///
|
||||
/// // But the map lens have been reduced by half
|
||||
/// // even if we do not use DrainFilter iterator.
|
||||
/// assert_eq!(map.len(), 4);
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub fn drain_filter<F>(&mut self, f: F) -> DrainFilter<'_, K, V, F, A>
|
||||
@@ -791,8 +909,14 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
|
||||
///
|
||||
/// let mut a = HashMap::new();
|
||||
/// a.insert(1, "a");
|
||||
/// let capacity_before_clear = a.capacity();
|
||||
///
|
||||
/// a.clear();
|
||||
///
|
||||
/// // Map is empty.
|
||||
/// assert!(a.is_empty());
|
||||
/// // But map capacity is equal to old one.
|
||||
/// assert_eq!(a.capacity(), capacity_before_clear);
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub fn clear(&mut self) {
|
||||
@@ -813,7 +937,12 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
|
||||
/// map.insert("b", 2);
|
||||
/// map.insert("c", 3);
|
||||
///
|
||||
/// let vec: Vec<&str> = map.into_keys().collect();
|
||||
/// let mut vec: Vec<&str> = map.into_keys().collect();
|
||||
///
|
||||
/// // The `IntoKeys` iterator produces keys in arbitrary order, so the
|
||||
/// // keys must be sorted to test them against a sorted array.
|
||||
/// vec.sort_unstable();
|
||||
/// assert_eq!(vec, ["a", "b", "c"]);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn into_keys(self) -> IntoKeys<K, V, A> {
|
||||
@@ -836,7 +965,12 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
|
||||
/// map.insert("b", 2);
|
||||
/// map.insert("c", 3);
|
||||
///
|
||||
/// let vec: Vec<i32> = map.into_values().collect();
|
||||
/// let mut vec: Vec<i32> = map.into_values().collect();
|
||||
///
|
||||
/// // The `IntoValues` iterator produces values in arbitrary order, so
|
||||
/// // the values must be sorted to test them against a sorted array.
|
||||
/// vec.sort_unstable();
|
||||
/// assert_eq!(vec, [1, 2, 3]);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn into_values(self) -> IntoValues<K, V, A> {
|
||||
@@ -867,7 +1001,13 @@ where
|
||||
/// ```
|
||||
/// use hashbrown::HashMap;
|
||||
/// let mut map: HashMap<&str, i32> = HashMap::new();
|
||||
/// // Map is empty and doesn't allocate memory
|
||||
/// assert_eq!(map.capacity(), 0);
|
||||
///
|
||||
/// map.reserve(10);
|
||||
///
|
||||
/// // And now map can hold at least 10 elements
|
||||
/// assert!(map.capacity() >= 10);
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub fn reserve(&mut self, additional: usize) {
|
||||
@@ -888,8 +1028,36 @@ where
|
||||
///
|
||||
/// ```
|
||||
/// use hashbrown::HashMap;
|
||||
///
|
||||
/// let mut map: HashMap<&str, isize> = HashMap::new();
|
||||
/// // Map is empty and doesn't allocate memory
|
||||
/// assert_eq!(map.capacity(), 0);
|
||||
///
|
||||
/// map.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?");
|
||||
///
|
||||
/// // And now map can hold at least 10 elements
|
||||
/// assert!(map.capacity() >= 10);
|
||||
/// ```
|
||||
/// If the capacity overflows, or the allocator reports a failure, then an error
|
||||
/// is returned:
|
||||
/// ```
|
||||
/// # fn test() {
|
||||
/// use hashbrown::HashMap;
|
||||
/// use hashbrown::TryReserveError;
|
||||
/// let mut map: HashMap<i32, i32> = HashMap::new();
|
||||
///
|
||||
/// match map.try_reserve(usize::MAX) {
|
||||
/// Err(error) => match error {
|
||||
/// TryReserveError::CapacityOverflow => {}
|
||||
/// _ => panic!("TryReserveError::AllocError ?"),
|
||||
/// },
|
||||
/// _ => panic!(),
|
||||
/// }
|
||||
/// # }
|
||||
/// # fn main() {
|
||||
/// # #[cfg(not(miri))]
|
||||
/// # test()
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
|
||||
@@ -1188,6 +1356,8 @@ where
|
||||
/// *x = "b";
|
||||
/// }
|
||||
/// assert_eq!(map[&1], "b");
|
||||
///
|
||||
/// assert_eq!(map.get_mut(&2), None);
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
|
||||
@@ -1273,7 +1443,7 @@ where
|
||||
/// Returns an array of length `N` with the results of each query. `None` will be returned if
|
||||
/// any of the keys are missing.
|
||||
///
|
||||
/// For a safe alternative see [`get_many_mut`].
|
||||
/// For a safe alternative see [`get_many_mut`](`HashMap::get_many_mut`).
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
@@ -1386,7 +1556,7 @@ where
|
||||
/// Returns an array of length `N` with the results of each query. `None` will be returned if
|
||||
/// any of the keys are missing.
|
||||
///
|
||||
/// For a safe alternative see [`get_many_key_value_mut`].
|
||||
/// For a safe alternative see [`get_many_key_value_mut`](`HashMap::get_many_key_value_mut`).
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
@@ -1480,11 +1650,12 @@ where
|
||||
///
|
||||
/// If the map did have this key present, the value is updated, and the old
|
||||
/// value is returned. The key is not updated, though; this matters for
|
||||
/// types that can be `==` without being identical. See the [module-level
|
||||
/// documentation] for more.
|
||||
/// types that can be `==` without being identical. See the [`std::collections`]
|
||||
/// [module-level documentation] for more.
|
||||
///
|
||||
/// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None
|
||||
/// [module-level documentation]: index.html#insert-and-complex-keys
|
||||
/// [`std::collections`]: https://doc.rust-lang.org/std/collections/index.html
|
||||
/// [module-level documentation]: https://doc.rust-lang.org/std/collections/index.html#insert-and-complex-keys
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@@ -1531,6 +1702,35 @@ where
|
||||
/// This operation is useful during initial population of the map.
|
||||
/// For example, when constructing a map from another map, we know
|
||||
/// that keys are unique.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use hashbrown::HashMap;
|
||||
///
|
||||
/// let mut map1 = HashMap::new();
|
||||
/// assert_eq!(map1.insert(1, "a"), None);
|
||||
/// assert_eq!(map1.insert(2, "b"), None);
|
||||
/// assert_eq!(map1.insert(3, "c"), None);
|
||||
/// assert_eq!(map1.len(), 3);
|
||||
///
|
||||
/// let mut map2 = HashMap::new();
|
||||
///
|
||||
/// for (key, value) in map1.into_iter() {
|
||||
/// map2.insert_unique_unchecked(key, value);
|
||||
/// }
|
||||
///
|
||||
/// let (key, value) = map2.insert_unique_unchecked(4, "d");
|
||||
/// assert_eq!(key, &4);
|
||||
/// assert_eq!(value, &mut "d");
|
||||
/// *value = "e";
|
||||
///
|
||||
/// assert_eq!(map2[&1], "a");
|
||||
/// assert_eq!(map2[&2], "b");
|
||||
/// assert_eq!(map2[&3], "c");
|
||||
/// assert_eq!(map2[&4], "e");
|
||||
/// assert_eq!(map2.len(), 4);
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub fn insert_unique_unchecked(&mut self, k: K, v: V) -> (&K, &mut V) {
|
||||
let hash = make_insert_hash::<K, S>(&self.hash_builder, &k);
|
||||
@@ -1555,14 +1755,19 @@ where
|
||||
///
|
||||
/// ```
|
||||
/// use hashbrown::HashMap;
|
||||
/// use hashbrown::hash_map::OccupiedError;
|
||||
///
|
||||
/// let mut map = HashMap::new();
|
||||
/// assert_eq!(map.try_insert(37, "a").unwrap(), &"a");
|
||||
///
|
||||
/// let err = map.try_insert(37, "b").unwrap_err();
|
||||
/// assert_eq!(err.entry.key(), &37);
|
||||
/// assert_eq!(err.entry.get(), &"a");
|
||||
/// assert_eq!(err.value, "b");
|
||||
/// match map.try_insert(37, "b") {
|
||||
/// Err(OccupiedError { entry, value }) => {
|
||||
/// assert_eq!(entry.key(), &37);
|
||||
/// assert_eq!(entry.get(), &"a");
|
||||
/// assert_eq!(value, "b");
|
||||
/// }
|
||||
/// _ => panic!()
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub fn try_insert(
|
||||
@@ -1577,7 +1782,7 @@ where
|
||||
}
|
||||
|
||||
/// Removes a key from the map, returning the value at the key if the key
|
||||
/// was previously in the map.
|
||||
/// was previously in the map. Keeps the allocated memory for reuse.
|
||||
///
|
||||
/// The key may be any borrowed form of the map's key type, but
|
||||
/// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
|
||||
@@ -1592,9 +1797,17 @@ where
|
||||
/// use hashbrown::HashMap;
|
||||
///
|
||||
/// let mut map = HashMap::new();
|
||||
/// // The map is empty
|
||||
/// assert!(map.is_empty() && map.capacity() == 0);
|
||||
///
|
||||
/// map.insert(1, "a");
|
||||
/// let capacity_before_remove = map.capacity();
|
||||
///
|
||||
/// assert_eq!(map.remove(&1), Some("a"));
|
||||
/// assert_eq!(map.remove(&1), None);
|
||||
///
|
||||
/// // Now map holds none elements but capacity is equal to the old one
|
||||
/// assert!(map.len() == 0 && map.capacity() == capacity_before_remove);
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
|
||||
@@ -1610,7 +1823,7 @@ where
|
||||
}
|
||||
|
||||
/// Removes a key from the map, returning the stored key and value if the
|
||||
/// key was previously in the map.
|
||||
/// key was previously in the map. Keeps the allocated memory for reuse.
|
||||
///
|
||||
/// The key may be any borrowed form of the map's key type, but
|
||||
/// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
|
||||
@@ -1625,9 +1838,17 @@ where
|
||||
/// use hashbrown::HashMap;
|
||||
///
|
||||
/// let mut map = HashMap::new();
|
||||
/// // The map is empty
|
||||
/// assert!(map.is_empty() && map.capacity() == 0);
|
||||
///
|
||||
/// map.insert(1, "a");
|
||||
/// let capacity_before_remove = map.capacity();
|
||||
///
|
||||
/// assert_eq!(map.remove_entry(&1), Some((1, "a")));
|
||||
/// assert_eq!(map.remove(&1), None);
|
||||
///
|
||||
/// // Now map hold none elements but capacity is equal to the old one
|
||||
/// assert!(map.len() == 0 && map.capacity() == capacity_before_remove);
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub fn remove_entry<Q: ?Sized>(&mut self, k: &Q) -> Option<(K, V)>
|
||||
@@ -1672,6 +1893,72 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
|
||||
/// so that the map now contains keys which compare equal, search may start
|
||||
/// acting erratically, with two keys randomly masking each other. Implementations
|
||||
/// are free to assume this doesn't happen (within the limits of memory-safety).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use hashbrown::{HashMap, hash_map::RawEntryMut};
|
||||
///
|
||||
/// let mut map = HashMap::new();
|
||||
/// map.extend([("a", 100), ("b", 200), ("c", 300)]);
|
||||
///
|
||||
/// let compute_hash = |map: &HashMap<&str, i32>, k: &str| -> u64 {
|
||||
/// use core::hash::{BuildHasher, Hash, Hasher};
|
||||
///
|
||||
/// let mut hasher = map.hasher().build_hasher();
|
||||
/// k.hash(&mut hasher);
|
||||
/// hasher.finish()
|
||||
/// };
|
||||
///
|
||||
/// // Existing key (insert and update)
|
||||
/// match map.raw_entry_mut().from_key(&"a") {
|
||||
/// RawEntryMut::Vacant(_) => unreachable!(),
|
||||
/// RawEntryMut::Occupied(mut view) => {
|
||||
/// assert_eq!(view.get(), &100);
|
||||
/// let v = view.get_mut();
|
||||
/// let new_v = (*v) * 10;
|
||||
/// *v = new_v;
|
||||
/// assert_eq!(view.insert(1111), 1000);
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(map[&"a"], 1111);
|
||||
/// assert_eq!(map.len(), 3);
|
||||
///
|
||||
/// // Existing key (take)
|
||||
/// let hash = compute_hash(&map, &"c");
|
||||
/// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &"c") {
|
||||
/// RawEntryMut::Vacant(_) => unreachable!(),
|
||||
/// RawEntryMut::Occupied(view) => {
|
||||
/// assert_eq!(view.remove_entry(), ("c", 300));
|
||||
/// }
|
||||
/// }
|
||||
/// assert_eq!(map.raw_entry().from_key(&"c"), None);
|
||||
/// assert_eq!(map.len(), 2);
|
||||
///
|
||||
/// // Nonexistent key (insert and update)
|
||||
/// let key = "d";
|
||||
/// let hash = compute_hash(&map, &key);
|
||||
/// match map.raw_entry_mut().from_hash(hash, |q| *q == key) {
|
||||
/// RawEntryMut::Occupied(_) => unreachable!(),
|
||||
/// RawEntryMut::Vacant(view) => {
|
||||
/// let (k, value) = view.insert("d", 4000);
|
||||
/// assert_eq!((*k, *value), ("d", 4000));
|
||||
/// *value = 40000;
|
||||
/// }
|
||||
/// }
|
||||
/// assert_eq!(map[&"d"], 40000);
|
||||
/// assert_eq!(map.len(), 3);
|
||||
///
|
||||
/// match map.raw_entry_mut().from_hash(hash, |q| *q == key) {
|
||||
/// RawEntryMut::Vacant(_) => unreachable!(),
|
||||
/// RawEntryMut::Occupied(view) => {
|
||||
/// assert_eq!(view.remove_entry(), ("d", 40000));
|
||||
/// }
|
||||
/// }
|
||||
/// assert_eq!(map.get(&"d"), None);
|
||||
/// assert_eq!(map.len(), 2);
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub fn raw_entry_mut(&mut self) -> RawEntryBuilderMut<'_, K, V, S, A> {
|
||||
RawEntryBuilderMut { map: self }
|
||||
@@ -1692,6 +1979,35 @@ impl<K, V, S, A: Allocator + Clone> HashMap<K, V, S, A> {
|
||||
/// `get` should be preferred.
|
||||
///
|
||||
/// Immutable raw entries have very limited use; you might instead want `raw_entry_mut`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use hashbrown::HashMap;
|
||||
///
|
||||
/// let mut map = HashMap::new();
|
||||
/// map.extend([("a", 100), ("b", 200), ("c", 300)]);
|
||||
///
|
||||
/// let compute_hash = |map: &HashMap<&str, i32>, k: &str| -> u64 {
|
||||
/// use core::hash::{BuildHasher, Hash, Hasher};
|
||||
///
|
||||
/// let mut hasher = map.hasher().build_hasher();
|
||||
/// k.hash(&mut hasher);
|
||||
/// hasher.finish()
|
||||
/// };
|
||||
///
|
||||
/// for k in ["a", "b", "c", "d", "e", "f"] {
|
||||
/// let hash = compute_hash(&map, k);
|
||||
/// let v = map.get(&k).cloned();
|
||||
/// let kv = v.as_ref().map(|v| (&k, v));
|
||||
///
|
||||
/// println!("Key: {} and value: {:?}", k, v);
|
||||
///
|
||||
/// assert_eq!(map.raw_entry().from_key(&k), kv);
|
||||
/// assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv);
|
||||
/// assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv);
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg_attr(feature = "inline-more", inline)]
|
||||
pub fn raw_entry(&self) -> RawEntryBuilder<'_, K, V, S, A> {
|
||||
RawEntryBuilder { map: self }
|
||||
|
||||
@@ -69,16 +69,10 @@ fn unlikely(b: bool) -> bool {
|
||||
b
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
#[inline]
|
||||
unsafe fn offset_from<T>(to: *const T, from: *const T) -> usize {
|
||||
to.offset_from(from) as usize
|
||||
}
|
||||
#[cfg(not(feature = "nightly"))]
|
||||
#[inline]
|
||||
unsafe fn offset_from<T>(to: *const T, from: *const T) -> usize {
|
||||
(to as usize - from as usize) / mem::size_of::<T>()
|
||||
}
|
||||
|
||||
/// Whether memory allocation errors should return an error or abort.
|
||||
#[derive(Copy, Clone)]
|
||||
|
||||
Reference in New Issue
Block a user