@@ -3926,6 +3926,42 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
39263926 & mut self . inner . into_mut ( ) . 1
39273927 }
39283928
3929+ /// Converts the `OccupiedEntry` into a reference to the key and a
3930+ /// mutable reference to the value in the entry with a lifetime bound to the
3931+ /// map itself.
3932+ ///
3933+ /// If you need multiple references to the `OccupiedEntry`, see [`key`] and
3934+ /// [`get_mut`].
3935+ ///
3936+ /// [`key`]: Self::key
3937+ /// [`get_mut`]: Self::get_mut
3938+ ///
3939+ /// # Examples
3940+ ///
3941+ /// ```
3942+ /// use hashbrown::hash_map::{Entry, HashMap};
3943+ ///
3944+ /// let mut map: HashMap<&str, u32> = HashMap::new();
3945+ /// map.entry("poneyland").or_insert(12);
3946+ ///
3947+ /// assert_eq!(map["poneyland"], 12);
3948+ ///
3949+ /// let key_val: (&&str, &mut u32);
3950+ /// match map.entry("poneyland") {
3951+ /// Entry::Occupied(entry) => key_val = entry.into_entry(),
3952+ /// Entry::Vacant(_) => panic!(),
3953+ /// }
3954+ /// *key_val.1 += 10;
3955+ ///
3956+ /// assert_eq!(key_val, (&"poneyland", &mut 22));
3957+ /// assert_eq!(map["poneyland"], 22);
3958+ /// ```
3959+ #[ cfg_attr( feature = "inline-more" , inline) ]
3960+ pub fn into_entry ( self ) -> ( & ' a K , & ' a mut V ) {
3961+ let ( key, val) = unsafe { self . elem . as_mut ( ) } ;
3962+ ( key, val)
3963+ }
3964+
39293965 /// Sets the value of the entry, and returns the entry's old value.
39303966 ///
39313967 /// # Examples
@@ -4476,11 +4512,7 @@ impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K,
44764512 Q : Equivalent < K > ,
44774513 S : BuildHasher ,
44784514 {
4479- assert ! (
4480- ( self . key) . equivalent( & key) ,
4481- "key used for Entry creation is not equivalent to the one used for insertion"
4482- ) ;
4483- & mut self . inner . insert ( ( key, value) ) . into_mut ( ) . 1
4515+ self . insert_entry_with_key ( key, value) . into_mut ( )
44844516 }
44854517
44864518 /// Sets the value of the entry with the [`VacantEntryRef`]'s key,
@@ -4511,6 +4543,51 @@ impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K,
45114543 marker : PhantomData ,
45124544 }
45134545 }
4546+
4547+ /// Sets the key and value of the entry and returns an [`OccupiedEntry`].
4548+ ///
4549+ /// Unlike [`VacantEntryRef::insert_entry`], this method allows the key to
4550+ /// be explicitly specified, which is useful for key types that don't
4551+ /// implement `K: From<&Q>`.
4552+ ///
4553+ /// # Panics
4554+ ///
4555+ /// This method panics if `key` is not equivalent to the key used to create
4556+ /// the `VacantEntryRef`.
4557+ ///
4558+ /// # Example
4559+ ///
4560+ /// ```
4561+ /// use hashbrown::hash_map::EntryRef;
4562+ /// use hashbrown::HashMap;
4563+ ///
4564+ /// let mut map = HashMap::<(String, String), char>::new();
4565+ /// let k = ("c".to_string(), "C".to_string());
4566+ /// let r = match map.entry_ref(&k) {
4567+ /// // Insert cannot be used here because tuples do not implement From.
4568+ /// // However this works because we can manually clone instead.
4569+ /// EntryRef::Vacant(r) => r.insert_entry_with_key(k.clone(), 'c'),
4570+ /// // In this branch we avoid the clone.
4571+ /// EntryRef::Occupied(r) => r,
4572+ /// };
4573+ /// assert_eq!(r.get(), &'c');
4574+ /// ```
4575+ #[ cfg_attr( feature = "inline-more" , inline) ]
4576+ pub fn insert_entry_with_key ( self , key : K , value : V ) -> OccupiedEntry < ' map , K , V , S , A >
4577+ where
4578+ K : Hash ,
4579+ Q : Equivalent < K > ,
4580+ S : BuildHasher ,
4581+ {
4582+ assert ! (
4583+ ( self . key) . equivalent( & key) ,
4584+ "key used for Entry creation is not equivalent to the one used for insertion"
4585+ ) ;
4586+ OccupiedEntry {
4587+ inner : self . inner . insert ( ( key, value) ) ,
4588+ marker : PhantomData ,
4589+ }
4590+ }
45144591}
45154592
45164593impl < K , V , S , A > FromIterator < ( K , V ) > for HashMap < K , V , S , A >
0 commit comments