@@ -3963,6 +3963,42 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
39633963 unsafe { & mut self . elem . as_mut ( ) . 1 }
39643964 }
39653965
3966+ /// Converts the `OccupiedEntry` into a reference to the key and a
3967+ /// mutable reference to the value in the entry with a lifetime bound to the
3968+ /// map itself.
3969+ ///
3970+ /// If you need multiple references to the `OccupiedEntry`, see [`key`] and
3971+ /// [`get_mut`].
3972+ ///
3973+ /// [`key`]: Self::key
3974+ /// [`get_mut`]: Self::get_mut
3975+ ///
3976+ /// # Examples
3977+ ///
3978+ /// ```
3979+ /// use hashbrown::hash_map::{Entry, HashMap};
3980+ ///
3981+ /// let mut map: HashMap<&str, u32> = HashMap::new();
3982+ /// map.entry("poneyland").or_insert(12);
3983+ ///
3984+ /// assert_eq!(map["poneyland"], 12);
3985+ ///
3986+ /// let key_val: (&&str, &mut u32);
3987+ /// match map.entry("poneyland") {
3988+ /// Entry::Occupied(entry) => key_val = entry.into_entry(),
3989+ /// Entry::Vacant(_) => panic!(),
3990+ /// }
3991+ /// *key_val.1 += 10;
3992+ ///
3993+ /// assert_eq!(key_val, (&"poneyland", &mut 22));
3994+ /// assert_eq!(map["poneyland"], 22);
3995+ /// ```
3996+ #[ cfg_attr( feature = "inline-more" , inline) ]
3997+ pub fn into_entry ( self ) -> ( & ' a K , & ' a mut V ) {
3998+ let ( key, val) = self . inner . into_mut ( ) ;
3999+ ( key, val)
4000+ }
4001+
39664002 /// Sets the value of the entry, and returns the entry's old value.
39674003 ///
39684004 /// # Examples
@@ -4535,17 +4571,7 @@ impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K,
45354571 Q : Equivalent < K > ,
45364572 S : BuildHasher ,
45374573 {
4538- let table = & mut self . table . table ;
4539- assert ! (
4540- ( self . key) . equivalent( & key) ,
4541- "key used for Entry creation is not equivalent to the one used for insertion"
4542- ) ;
4543- let entry = table. insert_entry (
4544- self . hash ,
4545- ( key, value) ,
4546- make_hasher :: < _ , V , S > ( & self . table . hash_builder ) ,
4547- ) ;
4548- & mut entry. 1
4574+ self . insert_entry_with_key ( key, value) . into_mut ( )
45494575 }
45504576
45514577 /// Sets the value of the entry with the [`VacantEntryRef`]'s key,
@@ -4582,6 +4608,57 @@ impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K,
45824608 table : self . table ,
45834609 }
45844610 }
4611+
4612+ /// Sets the key and value of the entry and returns an [`OccupiedEntry`].
4613+ ///
4614+ /// Unlike [`VacantEntryRef::insert_entry`], this method allows the key to
4615+ /// be explicitly specified, which is useful for key types that don't
4616+ /// implement `K: From<&Q>`.
4617+ ///
4618+ /// # Panics
4619+ ///
4620+ /// This method panics if `key` is not equivalent to the key used to create
4621+ /// the `VacantEntryRef`.
4622+ ///
4623+ /// # Example
4624+ ///
4625+ /// ```
4626+ /// use hashbrown::hash_map::EntryRef;
4627+ /// use hashbrown::HashMap;
4628+ ///
4629+ /// let mut map = HashMap::<(String, String), char>::new();
4630+ /// let k = ("c".to_string(), "C".to_string());
4631+ /// let v = match map.entry_ref(&k) {
4632+ /// // Insert cannot be used here because tuples do not implement From.
4633+ /// // However this works because we can manually clone instead.
4634+ /// EntryRef::Vacant(r) => r.insert_entry_with_key(k.clone(), 'c'),
4635+ /// // In this branch we avoid the clone.
4636+ /// EntryRef::Occupied(r) => r,
4637+ /// };
4638+ /// assert_eq!(r.get(), 'c');
4639+ /// ```
4640+ #[ cfg_attr( feature = "inline-more" , inline) ]
4641+ pub fn insert_entry_with_key ( self , key : K , value : V ) -> OccupiedEntry < ' map , K , V , S , A >
4642+ where
4643+ K : Hash ,
4644+ Q : Equivalent < K > ,
4645+ S : BuildHasher ,
4646+ {
4647+ assert ! (
4648+ ( self . key) . equivalent( & key) ,
4649+ "key used for Entry creation is not equivalent to the one used for insertion"
4650+ ) ;
4651+ let elem = self . table . table . insert (
4652+ self . hash ,
4653+ ( key, value) ,
4654+ make_hasher :: < _ , V , S > ( & self . table . hash_builder ) ,
4655+ ) ;
4656+ OccupiedEntry {
4657+ hash : self . hash ,
4658+ elem,
4659+ table : self . table ,
4660+ }
4661+ }
45854662}
45864663
45874664impl < K , V , S , A > FromIterator < ( K , V ) > for HashMap < K , V , S , A >
0 commit comments