Skip to content

Commit 670213f

Browse files
authored
Merge pull request #601 from braddunbar/or-default-entry
HashMap: #or_default_entry and #or_insert_entry
2 parents e514afe + 99761e4 commit 670213f

File tree

1 file changed

+68
-5
lines changed

1 file changed

+68
-5
lines changed

src/map.rs

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3524,6 +3524,38 @@ impl<'a, K, V, S, A: Allocator> Entry<'a, K, V, S, A> {
35243524
}
35253525
}
35263526

3527+
/// Ensures a value is in the entry by inserting the default if empty,
3528+
/// and returns an [`OccupiedEntry`].
3529+
///
3530+
/// # Examples
3531+
///
3532+
/// ```
3533+
/// use hashbrown::HashMap;
3534+
///
3535+
/// let mut map: HashMap<&str, u32> = HashMap::new();
3536+
///
3537+
/// // nonexistent key
3538+
/// let entry = map.entry("poneyland").or_insert_entry(3);
3539+
/// assert_eq!(entry.key(), &"poneyland");
3540+
/// assert_eq!(entry.get(), &3);
3541+
///
3542+
/// // existing key
3543+
/// let mut entry = map.entry("poneyland").or_insert_entry(10);
3544+
/// assert_eq!(entry.key(), &"poneyland");
3545+
/// assert_eq!(entry.get(), &3);
3546+
/// ```
3547+
#[cfg_attr(feature = "inline-more", inline)]
3548+
pub fn or_insert_entry(self, default: V) -> OccupiedEntry<'a, K, V, S, A>
3549+
where
3550+
K: Hash,
3551+
S: BuildHasher,
3552+
{
3553+
match self {
3554+
Entry::Occupied(entry) => entry,
3555+
Entry::Vacant(entry) => entry.insert_entry(default),
3556+
}
3557+
}
3558+
35273559
/// Ensures a value is in the entry by inserting the result of the default function if empty,
35283560
/// and returns a mutable reference to the value in the entry.
35293561
///
@@ -4330,6 +4362,39 @@ impl<'a, 'b, K, Q: ?Sized, V: Default, S, A: Allocator> EntryRef<'a, 'b, K, Q, V
43304362
EntryRef::Vacant(entry) => entry.insert(Default::default()),
43314363
}
43324364
}
4365+
4366+
/// Ensures a value is in the entry by inserting the default value if empty,
4367+
/// and returns an [`OccupiedEntry`].
4368+
///
4369+
/// # Examples
4370+
///
4371+
/// ```
4372+
/// use hashbrown::HashMap;
4373+
///
4374+
/// let mut map: HashMap<String, Option<u32>> = HashMap::new();
4375+
///
4376+
/// // nonexistent key
4377+
/// let entry = map.entry_ref("poneyland").or_default_entry();
4378+
/// assert_eq!(entry.key(), &"poneyland");
4379+
/// assert_eq!(entry.get(), &None);
4380+
///
4381+
/// // existing key
4382+
/// map.insert("horseland".to_string(), Some(3));
4383+
/// let entry = map.entry_ref("horseland").or_default_entry();
4384+
/// assert_eq!(entry.key(), &"horseland");
4385+
/// assert_eq!(entry.get(), &Some(3));
4386+
/// ```
4387+
#[cfg_attr(feature = "inline-more", inline)]
4388+
pub fn or_default_entry(self) -> OccupiedEntry<'a, K, V, S, A>
4389+
where
4390+
K: Hash + From<&'b Q>,
4391+
S: BuildHasher,
4392+
{
4393+
match self {
4394+
EntryRef::Occupied(entry) => entry,
4395+
EntryRef::Vacant(entry) => entry.insert_entry(Default::default()),
4396+
}
4397+
}
43334398
}
43344399

43354400
impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'a, 'b, K, Q, V, S, A> {
@@ -6164,7 +6229,7 @@ mod test_map {
61646229
}
61656230

61666231
for (k, v) in map {
6167-
println!("{}, {}", k, v);
6232+
println!("{k}, {v}");
61686233
}
61696234
}
61706235

@@ -6269,8 +6334,7 @@ mod test_map {
62696334
for ((key, value), (panic_in_clone, panic_in_drop)) in guard.iter().zip(iter) {
62706335
if *key != check_count {
62716336
return Err(format!(
6272-
"key != check_count,\nkey: `{}`,\ncheck_count: `{}`",
6273-
key, check_count
6337+
"key != check_count,\nkey: `{key}`,\ncheck_count: `{check_count}`"
62746338
));
62756339
}
62766340
if value.dropped
@@ -6297,8 +6361,7 @@ mod test_map {
62976361

62986362
if count != check_count {
62996363
return Err(format!(
6300-
"count != check_count,\ncount: `{}`,\ncheck_count: `{}`",
6301-
count, check_count
6364+
"count != check_count,\ncount: `{count}`,\ncheck_count: `{check_count}`"
63026365
));
63036366
}
63046367
core::mem::forget(guard);

0 commit comments

Comments
 (0)