Skip to content

Commit f705fc8

Browse files
committed
proof of concept
1 parent d76a3de commit f705fc8

File tree

1 file changed

+45
-9
lines changed

1 file changed

+45
-9
lines changed

src/map.rs

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2986,10 +2986,10 @@ where
29862986
/// }
29872987
/// assert!(map["b"] == 20 && map.len() == 2);
29882988
/// ```
2989-
pub struct VacantEntryRef<'a, 'b, K, Q: ?Sized, V, S, A: Allocator = Global> {
2989+
pub struct VacantEntryRef<'map, 'key, K, Q: ?Sized, V, S, A: Allocator = Global> {
29902990
hash: u64,
2991-
key: &'b Q,
2992-
table: &'a mut HashMap<K, V, S, A>,
2991+
key: &'key Q,
2992+
table: &'map mut HashMap<K, V, S, A>,
29932993
}
29942994

29952995
impl<K, Q, V, S, A> Debug for VacantEntryRef<'_, '_, K, Q, V, S, A>
@@ -4330,7 +4330,25 @@ impl<'a, 'b, K, Q: ?Sized, V: Default, S, A: Allocator> EntryRef<'a, 'b, K, Q, V
43304330
}
43314331
}
43324332

4333-
impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'a, 'b, K, Q, V, S, A> {
4333+
impl<'map, 'key, K, V, S, A: Allocator> VacantEntryRef<'map, 'key, K, K, V, S, A> {
4334+
/// insert, cloing the key
4335+
#[cfg_attr(feature = "inline-more", inline)]
4336+
pub fn insert_clone(self, value: V) -> &'map mut V
4337+
where
4338+
K: Hash + Clone,
4339+
S: BuildHasher,
4340+
{
4341+
let table = &mut self.table.table;
4342+
let entry = table.insert_entry(
4343+
self.hash,
4344+
(self.key.clone(), value),
4345+
make_hasher::<_, V, S>(&self.table.hash_builder),
4346+
);
4347+
&mut entry.1
4348+
}
4349+
}
4350+
4351+
impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K, Q, V, S, A> {
43344352
/// Gets a reference to the key that would be used when inserting a value
43354353
/// through the `VacantEntryRef`.
43364354
///
@@ -4344,7 +4362,7 @@ impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'a, 'b, K, Q, V, S
43444362
/// assert_eq!(map.entry_ref(key).key(), "poneyland");
43454363
/// ```
43464364
#[cfg_attr(feature = "inline-more", inline)]
4347-
pub fn key(&self) -> &'b Q {
4365+
pub fn key(&self) -> &'key Q {
43484366
self.key
43494367
}
43504368

@@ -4366,9 +4384,9 @@ impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'a, 'b, K, Q, V, S
43664384
/// assert_eq!(map["poneyland"], 37);
43674385
/// ```
43684386
#[cfg_attr(feature = "inline-more", inline)]
4369-
pub fn insert(self, value: V) -> &'a mut V
4387+
pub fn insert(self, value: V) -> &'map mut V
43704388
where
4371-
K: Hash + From<&'b Q>,
4389+
K: Hash + From<&'key Q>,
43724390
S: BuildHasher,
43734391
{
43744392
let table = &mut self.table.table;
@@ -4380,6 +4398,24 @@ impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'a, 'b, K, Q, V, S
43804398
&mut entry.1
43814399
}
43824400

4401+
/// provide explicit key at insert-time instead of relying on there being effectively a from &K to K implementation and not working with cloneable values
4402+
#[cfg_attr(feature = "inline-more", inline)]
4403+
pub fn insert_kv(self, key: K, value: V) -> &'map mut V
4404+
where
4405+
K: Hash,
4406+
for<'k> &'k K: PartialEq<&'key Q>,
4407+
S: BuildHasher,
4408+
{
4409+
let table = &mut self.table.table;
4410+
assert!(&key == self.key);
4411+
let entry = table.insert_entry(
4412+
self.hash,
4413+
(key, value),
4414+
make_hasher::<_, V, S>(&self.table.hash_builder),
4415+
);
4416+
&mut entry.1
4417+
}
4418+
43834419
/// Sets the value of the entry with the [`VacantEntryRef`]'s key,
43844420
/// and returns an [`OccupiedEntry`].
43854421
///
@@ -4397,9 +4433,9 @@ impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'a, 'b, K, Q, V, S
43974433
/// }
43984434
/// ```
43994435
#[cfg_attr(feature = "inline-more", inline)]
4400-
pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, S, A>
4436+
pub fn insert_entry(self, value: V) -> OccupiedEntry<'map, K, V, S, A>
44014437
where
4402-
K: Hash + From<&'b Q>,
4438+
K: Hash + From<&'key Q>,
44034439
S: BuildHasher,
44044440
{
44054441
let elem = self.table.table.insert(

0 commit comments

Comments
 (0)