Skip to content

Commit 6028aac

Browse files
committed
proof of concept
1 parent eea9804 commit 6028aac

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
@@ -2984,10 +2984,10 @@ where
29842984
/// }
29852985
/// assert!(map["b"] == 20 && map.len() == 2);
29862986
/// ```
2987-
pub struct VacantEntryRef<'a, 'b, K, Q: ?Sized, V, S, A: Allocator = Global> {
2987+
pub struct VacantEntryRef<'map, 'key, K, Q: ?Sized, V, S, A: Allocator = Global> {
29882988
hash: u64,
2989-
key: &'b Q,
2990-
table: &'a mut HashMap<K, V, S, A>,
2989+
key: &'key Q,
2990+
table: &'map mut HashMap<K, V, S, A>,
29912991
}
29922992

29932993
impl<K, Q, V, S, A> Debug for VacantEntryRef<'_, '_, K, Q, V, S, A>
@@ -4328,7 +4328,25 @@ impl<'a, 'b, K, Q: ?Sized, V: Default, S, A: Allocator> EntryRef<'a, 'b, K, Q, V
43284328
}
43294329
}
43304330

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

@@ -4364,9 +4382,9 @@ impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'a, 'b, K, Q, V, S
43644382
/// assert_eq!(map["poneyland"], 37);
43654383
/// ```
43664384
#[cfg_attr(feature = "inline-more", inline)]
4367-
pub fn insert(self, value: V) -> &'a mut V
4385+
pub fn insert(self, value: V) -> &'map mut V
43684386
where
4369-
K: Hash + From<&'b Q>,
4387+
K: Hash + From<&'key Q>,
43704388
S: BuildHasher,
43714389
{
43724390
let table = &mut self.table.table;
@@ -4378,6 +4396,24 @@ impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'a, 'b, K, Q, V, S
43784396
&mut entry.1
43794397
}
43804398

4399+
/// 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
4400+
#[cfg_attr(feature = "inline-more", inline)]
4401+
pub fn insert_kv(self, key: K, value: V) -> &'map mut V
4402+
where
4403+
K: Hash,
4404+
for<'k> &'k K: PartialEq<&'key Q>,
4405+
S: BuildHasher,
4406+
{
4407+
let table = &mut self.table.table;
4408+
assert!(&key == self.key);
4409+
let entry = table.insert_entry(
4410+
self.hash,
4411+
(key, value),
4412+
make_hasher::<_, V, S>(&self.table.hash_builder),
4413+
);
4414+
&mut entry.1
4415+
}
4416+
43814417
/// Sets the value of the entry with the [`VacantEntryRef`]'s key,
43824418
/// and returns an [`OccupiedEntry`].
43834419
///
@@ -4395,9 +4431,9 @@ impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'a, 'b, K, Q, V, S
43954431
/// }
43964432
/// ```
43974433
#[cfg_attr(feature = "inline-more", inline)]
4398-
pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, S, A>
4434+
pub fn insert_entry(self, value: V) -> OccupiedEntry<'map, K, V, S, A>
43994435
where
4400-
K: Hash + From<&'b Q>,
4436+
K: Hash + From<&'key Q>,
44014437
S: BuildHasher,
44024438
{
44034439
let elem = self.table.table.insert(

0 commit comments

Comments
 (0)