usecrate::Equivalent; usecrate::alloc::{Allocator, Global}; usecrate::map::{HashMap, equivalent, make_hash, make_hasher}; usecrate::raw::{Bucket, RawTable}; use core::fmt::{self, Debug}; use core::hash::{BuildHasher, Hash}; use core::mem;
impl<K, V, S, A: Allocator> HashMap<K, V, S, A> { /// Creates a raw entry builder for the `HashMap`. /// /// Raw entries provide the lowest level of control for searching and /// manipulating a map. They must be manually initialized with a hash and /// then manually searched. After this, insertions into a vacant entry /// still require an owned key to be provided. /// /// Raw entries are useful for such exotic situations as: /// /// * Hash memoization /// * Deferring the creation of an owned key until it is known to be required /// * Using a search key that doesn't work with the Borrow trait /// * Using custom comparison logic without newtype wrappers /// /// Because raw entries provide much more low-level control, it's much easier /// to put the `HashMap` into an inconsistent state which, while memory-safe, /// will cause the map to produce seemingly random results. Higher-level and /// more foolproof APIs like `entry` should be preferred when possible. /// /// In particular, the hash used to initialized the raw entry must still be /// consistent with the hash of the key that is ultimately stored in the entry. /// This is because implementations of `HashMap` may need to recompute hashes /// when resizing, at which point only the keys are available. /// /// Raw entries give mutable access to the keys. This must not be used /// to modify how the key would compare or hash, as the map will not re-evaluate /// where the key should go, meaning the keys may become "lost" if their /// location does not reflect their state. For instance, if you change a key /// 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 core::hash::{BuildHasher, Hash}; /// use hashbrown::hash_map::{HashMap, RawEntryMut}; /// /// let mut map = HashMap::new(); /// map.extend([("a", 100), ("b", 200), ("c", 300)]); /// /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 { /// use core::hash::Hasher; /// let mut state = hash_builder.build_hasher(); /// key.hash(&mut state); /// state.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.hasher(), &"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.hasher(), &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)] pubfn raw_entry_mut(&mutself) -> RawEntryBuilderMut<'_, K, V, S, A> {
RawEntryBuilderMut { map: self }
}
/// Creates a raw immutable entry builder for the `HashMap`. /// /// Raw entries provide the lowest level of control for searching and /// manipulating a map. They must be manually initialized with a hash and /// then manually searched. /// /// This is useful for /// * Hash memoization /// * Using a search key that doesn't work with the Borrow trait /// * Using custom comparison logic without newtype wrappers /// /// Unless you are in such a situation, higher-level and more foolproof APIs like /// `get` should be preferred. /// /// Immutable raw entries have very limited use; you might instead want `raw_entry_mut`. /// /// # Examples /// /// ``` /// use core::hash::{BuildHasher, Hash}; /// use hashbrown::HashMap; /// /// let mut map = HashMap::new(); /// map.extend([("a", 100), ("b", 200), ("c", 300)]); /// /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 { /// use core::hash::Hasher; /// let mut state = hash_builder.build_hasher(); /// key.hash(&mut state); /// state.finish() /// } /// /// for k in ["a", "b", "c", "d", "e", "f"] { /// let hash = compute_hash(map.hasher(), 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)] pubfn raw_entry(&self) -> RawEntryBuilder<'_, K, V, S, A> {
RawEntryBuilder { map: self }
}
}
/// A builder for computing where in a [`HashMap`] a key-value pair would be stored. /// /// See the [`HashMap::raw_entry_mut`] docs for usage examples. /// /// [`HashMap::raw_entry_mut`]: HashMap::raw_entry_mut /// /// # Examples /// /// ``` /// use hashbrown::hash_map::{RawEntryBuilderMut, RawEntryMut::Vacant, RawEntryMut::Occupied}; /// use hashbrown::HashMap; /// use core::hash::{BuildHasher, Hash}; /// /// let mut map = HashMap::new(); /// map.extend([(1, 11), (2, 12), (3, 13), (4, 14), (5, 15), (6, 16)]); /// assert_eq!(map.len(), 6); /// /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 { /// use core::hash::Hasher; /// let mut state = hash_builder.build_hasher(); /// key.hash(&mut state); /// state.finish() /// } /// /// let builder: RawEntryBuilderMut<_, _, _> = map.raw_entry_mut(); /// /// // Existing key /// match builder.from_key(&6) { /// Vacant(_) => unreachable!(), /// Occupied(view) => assert_eq!(view.get(), &16), /// } /// /// for key in 0..12 { /// let hash = compute_hash(map.hasher(), &key); /// let value = map.get(&key).cloned(); /// let key_value = value.as_ref().map(|v| (&key, v)); /// /// println!("Key: {} and value: {:?}", key, value); /// /// match map.raw_entry_mut().from_key(&key) { /// Occupied(mut o) => assert_eq!(Some(o.get_key_value()), key_value), /// Vacant(_) => assert_eq!(value, None), /// } /// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &key) { /// Occupied(mut o) => assert_eq!(Some(o.get_key_value()), key_value), /// Vacant(_) => assert_eq!(value, None), /// } /// match map.raw_entry_mut().from_hash(hash, |q| *q == key) { /// Occupied(mut o) => assert_eq!(Some(o.get_key_value()), key_value), /// Vacant(_) => assert_eq!(value, None), /// } /// } /// /// assert_eq!(map.len(), 6); /// ``` pubstruct RawEntryBuilderMut<'a, K, V, S, A: Allocator = Global> {
map: &'a mut HashMap<K, V, S, A>,
}
/// A view into a single entry in a map, which may either be vacant or occupied. /// /// This is a lower-level version of [`Entry`]. /// /// [`Entry`]: crate::hash_map::Entry /// /// This `enum` is constructed through the [`raw_entry_mut`] method on [`HashMap`], /// then calling one of the methods of that [`RawEntryBuilderMut`]. /// /// [`raw_entry_mut`]: HashMap::raw_entry_mut /// /// # Examples /// /// ``` /// use core::hash::{BuildHasher, Hash}; /// use hashbrown::hash_map::{HashMap, RawEntryMut, RawOccupiedEntryMut}; /// /// let mut map = HashMap::new(); /// map.extend([('a', 1), ('b', 2), ('c', 3)]); /// assert_eq!(map.len(), 3); /// /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 { /// use core::hash::Hasher; /// let mut state = hash_builder.build_hasher(); /// key.hash(&mut state); /// state.finish() /// } /// /// // Existing key (insert) /// let raw: RawEntryMut<_, _, _> = map.raw_entry_mut().from_key(&'a'); /// let _raw_o: RawOccupiedEntryMut<_, _, _> = raw.insert('a', 10); /// assert_eq!(map.len(), 3); /// /// // Nonexistent key (insert) /// map.raw_entry_mut().from_key(&'d').insert('d', 40); /// assert_eq!(map.len(), 4); /// /// // Existing key (or_insert) /// let hash = compute_hash(map.hasher(), &'b'); /// let kv = map /// .raw_entry_mut() /// .from_key_hashed_nocheck(hash, &'b') /// .or_insert('b', 20); /// assert_eq!(kv, (&mut 'b', &mut 2)); /// *kv.1 = 20; /// assert_eq!(map.len(), 4); /// /// // Nonexistent key (or_insert) /// let hash = compute_hash(map.hasher(), &'e'); /// let kv = map /// .raw_entry_mut() /// .from_key_hashed_nocheck(hash, &'e') /// .or_insert('e', 50); /// assert_eq!(kv, (&mut 'e', &mut 50)); /// assert_eq!(map.len(), 5); /// /// // Existing key (or_insert_with) /// let hash = compute_hash(map.hasher(), &'c'); /// let kv = map /// .raw_entry_mut() /// .from_hash(hash, |q| q == &'c') /// .or_insert_with(|| ('c', 30)); /// assert_eq!(kv, (&mut 'c', &mut 3)); /// *kv.1 = 30; /// assert_eq!(map.len(), 5); /// /// // Nonexistent key (or_insert_with) /// let hash = compute_hash(map.hasher(), &'f'); /// let kv = map /// .raw_entry_mut() /// .from_hash(hash, |q| q == &'f') /// .or_insert_with(|| ('f', 60)); /// assert_eq!(kv, (&mut 'f', &mut 60)); /// assert_eq!(map.len(), 6); /// /// println!("Our HashMap: {:?}", map); /// /// let mut vec: Vec<_> = map.iter().map(|(&k, &v)| (k, v)).collect(); /// // 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', 10), ('b', 20), ('c', 30), ('d', 40), ('e', 50), ('f', 60)]); /// ``` pubenum RawEntryMut<'a, K, V, S, A: Allocator = Global> { /// An occupied entry. /// /// # Examples /// /// ``` /// use hashbrown::{hash_map::RawEntryMut, HashMap}; /// let mut map: HashMap<_, _> = [("a", 100), ("b", 200)].into(); /// /// match map.raw_entry_mut().from_key(&"a") { /// RawEntryMut::Vacant(_) => unreachable!(), /// RawEntryMut::Occupied(_) => { } /// } /// ```
Occupied(RawOccupiedEntryMut<'a, K, V, S, A>), /// A vacant entry. /// /// # Examples /// /// ``` /// use hashbrown::{hash_map::RawEntryMut, HashMap}; /// let mut map: HashMap<&str, i32> = HashMap::new(); /// /// match map.raw_entry_mut().from_key("a") { /// RawEntryMut::Occupied(_) => unreachable!(), /// RawEntryMut::Vacant(_) => { } /// } /// ```
Vacant(RawVacantEntryMut<'a, K, V, S, A>),
}
/// A view into an occupied entry in a `HashMap`. /// It is part of the [`RawEntryMut`] enum. /// /// # Examples /// /// ``` /// use core::hash::{BuildHasher, Hash}; /// use hashbrown::hash_map::{HashMap, RawEntryMut, RawOccupiedEntryMut}; /// /// let mut map = HashMap::new(); /// map.extend([("a", 10), ("b", 20), ("c", 30)]); /// /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 { /// use core::hash::Hasher; /// let mut state = hash_builder.build_hasher(); /// key.hash(&mut state); /// state.finish() /// } /// /// let _raw_o: RawOccupiedEntryMut<_, _, _> = map.raw_entry_mut().from_key(&"a").insert("a", 100); /// assert_eq!(map.len(), 3); /// /// // 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.hasher(), &"c"); /// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &"c") { /// RawEntryMut::Vacant(_) => unreachable!(), /// RawEntryMut::Occupied(view) => { /// assert_eq!(view.remove_entry(), ("c", 30)); /// } /// } /// assert_eq!(map.raw_entry().from_key(&"c"), None); /// assert_eq!(map.len(), 2); /// /// let hash = compute_hash(map.hasher(), &"b"); /// match map.raw_entry_mut().from_hash(hash, |q| *q == "b") { /// RawEntryMut::Vacant(_) => unreachable!(), /// RawEntryMut::Occupied(view) => { /// assert_eq!(view.remove_entry(), ("b", 20)); /// } /// } /// assert_eq!(map.get(&"b"), None); /// assert_eq!(map.len(), 1); /// ``` pubstruct RawOccupiedEntryMut<'a, K, V, S, A: Allocator = Global> {
elem: Bucket<(K, V)>,
table: &'a mut RawTable<(K, V), A>,
hash_builder: &'a S,
}
unsafeimpl<K, V, S, A> Send for RawOccupiedEntryMut<'_, K, V, S, A> where
K: Send,
V: Send,
S: Send,
A: Send + Allocator,
{
} unsafeimpl<K, V, S, A> Sync for RawOccupiedEntryMut<'_, K, V, S, A> where
K: Sync,
V: Sync,
S: Sync,
A: Sync + Allocator,
{
}
/// A view into a vacant entry in a `HashMap`. /// It is part of the [`RawEntryMut`] enum. /// /// # Examples /// /// ``` /// use core::hash::{BuildHasher, Hash}; /// use hashbrown::hash_map::{HashMap, RawEntryMut, RawVacantEntryMut}; /// /// let mut map = HashMap::<&str, i32>::new(); /// /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 { /// use core::hash::Hasher; /// let mut state = hash_builder.build_hasher(); /// key.hash(&mut state); /// state.finish() /// } /// /// let raw_v: RawVacantEntryMut<_, _, _> = match map.raw_entry_mut().from_key(&"a") { /// RawEntryMut::Vacant(view) => view, /// RawEntryMut::Occupied(_) => unreachable!(), /// }; /// raw_v.insert("a", 10); /// assert!(map[&"a"] == 10 && map.len() == 1); /// /// // Nonexistent key (insert and update) /// let hash = compute_hash(map.hasher(), &"b"); /// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &"b") { /// RawEntryMut::Occupied(_) => unreachable!(), /// RawEntryMut::Vacant(view) => { /// let (k, value) = view.insert("b", 2); /// assert_eq!((*k, *value), ("b", 2)); /// *value = 20; /// } /// } /// assert!(map[&"b"] == 20 && map.len() == 2); /// /// let hash = compute_hash(map.hasher(), &"c"); /// match map.raw_entry_mut().from_hash(hash, |q| *q == "c") { /// RawEntryMut::Occupied(_) => unreachable!(), /// RawEntryMut::Vacant(view) => { /// assert_eq!(view.insert("c", 30), (&mut "c", &mut 30)); /// } /// } /// assert!(map[&"c"] == 30 && map.len() == 3); /// ``` pubstruct RawVacantEntryMut<'a, K, V, S, A: Allocator = Global> {
table: &'a mut RawTable<(K, V), A>,
hash_builder: &'a S,
}
/// A builder for computing where in a [`HashMap`] a key-value pair would be stored. /// /// See the [`HashMap::raw_entry`] docs for usage examples. /// /// [`HashMap::raw_entry`]: HashMap::raw_entry /// /// # Examples /// /// ``` /// use hashbrown::hash_map::{HashMap, RawEntryBuilder}; /// use core::hash::{BuildHasher, Hash}; /// /// let mut map = HashMap::new(); /// map.extend([(1, 10), (2, 20), (3, 30)]); /// /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 { /// use core::hash::Hasher; /// let mut state = hash_builder.build_hasher(); /// key.hash(&mut state); /// state.finish() /// } /// /// for k in 0..6 { /// let hash = compute_hash(map.hasher(), &k); /// let v = map.get(&k).cloned(); /// let kv = v.as_ref().map(|v| (&k, v)); /// /// println!("Key: {} and value: {:?}", k, v); /// let builder: RawEntryBuilder<_, _, _> = map.raw_entry(); /// assert_eq!(builder.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); /// } /// ``` pubstruct RawEntryBuilder<'a, K, V, S, A: Allocator = Global> {
map: &'a HashMap<K, V, S, A>,
}
impl<'a, K, V, S, A: Allocator> RawEntryBuilderMut<'a, K, V, S, A> { /// Creates a `RawEntryMut` from the given key. /// /// # Examples /// /// ``` /// use hashbrown::hash_map::{HashMap, RawEntryMut}; /// /// let mut map: HashMap<&str, u32> = HashMap::new(); /// let key = "a"; /// let entry: RawEntryMut<&str, u32, _> = map.raw_entry_mut().from_key(&key); /// entry.insert(key, 100); /// assert_eq!(map[&"a"], 100); /// ``` #[cfg_attr(feature = "inline-more", inline)] pubfn from_key<Q>(self, k: &Q) -> RawEntryMut<'a, K, V, S, A> where
S: BuildHasher,
Q: Hash + Equivalent<K> + ?Sized,
{ let hash = make_hash::<Q, S>(&self.map.hash_builder, k); self.from_key_hashed_nocheck(hash, k)
}
/// Creates a `RawEntryMut` from the given key and its hash. /// /// # Examples /// /// ``` /// use core::hash::{BuildHasher, Hash}; /// use hashbrown::hash_map::{HashMap, RawEntryMut}; /// /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 { /// use core::hash::Hasher; /// let mut state = hash_builder.build_hasher(); /// key.hash(&mut state); /// state.finish() /// } /// /// let mut map: HashMap<&str, u32> = HashMap::new(); /// let key = "a"; /// let hash = compute_hash(map.hasher(), &key); /// let entry: RawEntryMut<&str, u32, _> = map.raw_entry_mut().from_key_hashed_nocheck(hash, &key); /// entry.insert(key, 100); /// assert_eq!(map[&"a"], 100); /// ``` #[inline] pubfn from_key_hashed_nocheck<Q>(self, hash: u64, k: &Q) -> RawEntryMut<'a, K, V, S, A> where
Q: Equivalent<K> + ?Sized,
{ self.from_hash(hash, equivalent(k))
}
}
impl<'a, K, V, S, A: Allocator> RawEntryBuilderMut<'a, K, V, S, A> { /// Creates a `RawEntryMut` from the given hash and matching function. /// /// # Examples /// /// ``` /// use core::hash::{BuildHasher, Hash}; /// use hashbrown::hash_map::{HashMap, RawEntryMut}; /// /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 { /// use core::hash::Hasher; /// let mut state = hash_builder.build_hasher(); /// key.hash(&mut state); /// state.finish() /// } /// /// let mut map: HashMap<&str, u32> = HashMap::new(); /// let key = "a"; /// let hash = compute_hash(map.hasher(), &key); /// let entry: RawEntryMut<&str, u32, _> = map.raw_entry_mut().from_hash(hash, |k| k == &key); /// entry.insert(key, 100); /// assert_eq!(map[&"a"], 100); /// ``` #[cfg_attr(feature = "inline-more", inline)] pubfn from_hash<F>(self, hash: u64, is_match: F) -> RawEntryMut<'a, K, V, S, A> where for<'b> F: FnMut(&'b K) -> bool,
{ self.search(hash, is_match)
}
/// Access an immutable entry by hash and matching function. /// /// # Examples /// /// ``` /// use core::hash::{BuildHasher, Hash}; /// use hashbrown::HashMap; /// /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 { /// use core::hash::Hasher; /// let mut state = hash_builder.build_hasher(); /// key.hash(&mut state); /// state.finish() /// } /// /// let map: HashMap<&str, u32> = [("a", 100), ("b", 200)].into(); /// let key = "a"; /// let hash = compute_hash(map.hasher(), &key); /// assert_eq!(map.raw_entry().from_hash(hash, |k| k == &key), Some((&"a", &100))); /// ``` #[cfg_attr(feature = "inline-more", inline)] pubfn from_hash<F>(self, hash: u64, is_match: F) -> Option<(&'a K, &'an>a V)> where
F: FnMut(&K) -> bool,
{ self.search(hash, is_match)
}
}
impl<'a, K, V, S, A: Allocator> RawEntryMut<'a, K, V, S, A> { /// Sets the value of the entry, and returns a `RawOccupiedEntryMut`. /// /// # Examples /// /// ``` /// use hashbrown::HashMap; /// /// let mut map: HashMap<&str, u32> = HashMap::new(); /// let entry = map.raw_entry_mut().from_key("horseyland").insert("horseyland", 37); /// /// assert_eq!(entry.remove_entry(), ("horseyland", 37)); /// ``` #[cfg_attr(feature = "inline-more", inline)] pubfn insert(self, key: K, value: V) -> RawOccupiedEntryMut<'a, K, V, S, A> where
K: Hash,
S: BuildHasher,
{ matchself {
RawEntryMut::Occupied(mut entry) => {
entry.insert(value);
entry
}
RawEntryMut::Vacant(entry) => entry.insert_entry(key, value),
}
}
/// Ensures a value is in the entry by inserting the default if empty, and returns /// mutable references to the key and value in the entry. /// /// # Examples /// /// ``` /// use hashbrown::HashMap; /// /// let mut map: HashMap<&str, u32> = HashMap::new(); /// /// map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 3); /// assert_eq!(map["poneyland"], 3); /// /// *map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 10).1 *= 2; /// assert_eq!(map["poneyland"], 6); /// ``` #[cfg_attr(feature = "inline-more", inline)] pubfn or_insert(self, default_key: K, default_val: V) -> (&'a mut K, &'a mut V) where
K: Hash,
S: BuildHasher,
{ matchself {
RawEntryMut::Occupied(entry) => entry.into_key_value(),
RawEntryMut::Vacant(entry) => entry.insert(default_key, default_val),
}
}
/// Ensures a value is in the entry by inserting the result of the default function if empty, /// and returns mutable references to the key and value in the entry. /// /// # Examples /// /// ``` /// use hashbrown::HashMap; /// /// let mut map: HashMap<&str, String> = HashMap::new(); /// /// map.raw_entry_mut().from_key("poneyland").or_insert_with(|| { /// ("poneyland", "hoho".to_string()) /// }); /// /// assert_eq!(map["poneyland"], "hoho".to_string()); /// ``` #[cfg_attr(feature = "inline-more", inline)] pubfn or_insert_with<F>(self, default: F) -> (&'a mut K, &'a mut V) where
F: FnOnce() -> (K, V),
K: Hash,
S: BuildHasher,
{ matchself {
RawEntryMut::Occupied(entry) => entry.into_key_value(),
RawEntryMut::Vacant(entry) => { let (k, v) = default();
entry.insert(k, v)
}
}
}
// Ensure all lookup methods produce equivalent results. for k in0..12 { let hash = compute_hash(&map, k); let v = map.get(&k).copied(); let kv = v.as_ref().map(|v| (&k, v));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.