Skip to content

Commit 7d938df

Browse files
committed
Adding Extend<&'a (K, V)> for HashMap<K, V, S, A>
1 parent 3dbcdcc commit 7d938df

File tree

1 file changed

+92
-1
lines changed

1 file changed

+92
-1
lines changed

src/map.rs

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5973,6 +5973,66 @@ where
59735973
}
59745974
}
59755975

5976+
/// Inserts all new key-values from the iterator and replaces values with existing
5977+
/// keys with new values returned from the iterator.
5978+
impl<'a, K, V, S, A> Extend<&'a (K, V)> for HashMap<K, V, S, A>
5979+
where
5980+
K: Eq + Hash + Copy,
5981+
V: Copy,
5982+
S: BuildHasher,
5983+
A: Allocator + Clone,
5984+
{
5985+
/// Inserts all new key-values from the iterator to existing `HashMap<K, V, S, A>`.
5986+
/// Replace values with existing keys with new values returned from the iterator.
5987+
/// The keys and values must implement [`Copy`] trait.
5988+
///
5989+
/// [`Copy`]: https://doc.rust-lang.org/core/marker/trait.Copy.html
5990+
///
5991+
/// # Examples
5992+
///
5993+
/// ```
5994+
/// use hashbrown::hash_map::HashMap;
5995+
///
5996+
/// let mut map = HashMap::new();
5997+
/// map.insert(1, 100);
5998+
///
5999+
/// let arr = [(1, 1), (2, 2)];
6000+
/// let some_iter = arr.iter();
6001+
/// map.extend(some_iter);
6002+
/// // Replace values with existing keys with new values returned from the iterator.
6003+
/// // So that the map.get(&1) doesn't return Some(&100).
6004+
/// assert_eq!(map.get(&1), Some(&1));
6005+
///
6006+
/// let some_vec: Vec<_> = vec![(3, 3), (4, 4)];
6007+
/// map.extend(&some_vec);
6008+
///
6009+
/// let some_arr = [(5, 5), (6, 6)];
6010+
/// map.extend(&some_arr);
6011+
///
6012+
/// let mut vec: Vec<_> = map.into_iter().collect();
6013+
/// // The `IntoIter` iterator produces items in arbitrary order, so the
6014+
/// // items must be sorted to test them against a sorted array.
6015+
/// vec.sort_unstable();
6016+
/// assert_eq!(vec, [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]);
6017+
/// ```
6018+
#[cfg_attr(feature = "inline-more", inline)]
6019+
fn extend<T: IntoIterator<Item = &'a (K, V)>>(&mut self, iter: T) {
6020+
self.extend(iter.into_iter().map(|&(key, value)| (key, value)));
6021+
}
6022+
6023+
#[inline]
6024+
#[cfg(feature = "nightly")]
6025+
fn extend_one(&mut self, &(k, v): &'a (K, V)) {
6026+
self.insert(k, v);
6027+
}
6028+
6029+
#[inline]
6030+
#[cfg(feature = "nightly")]
6031+
fn extend_reserve(&mut self, additional: usize) {
6032+
Extend::<(K, V)>::extend_reserve(self, additional);
6033+
}
6034+
}
6035+
59766036
#[allow(dead_code)]
59776037
fn assert_covariance() {
59786038
fn map_key<'new>(v: HashMap<&'static str, u8>) -> HashMap<&'new str, u8> {
@@ -6960,7 +7020,7 @@ mod test_map {
69607020
}
69617021

69627022
#[test]
6963-
fn test_extend_ref() {
7023+
fn test_extend_ref_k_ref_v() {
69647024
let mut a = HashMap::new();
69657025
a.insert(1, "one");
69667026
let mut b = HashMap::new();
@@ -6975,6 +7035,37 @@ mod test_map {
69757035
assert_eq!(a[&3], "three");
69767036
}
69777037

7038+
#[test]
7039+
fn test_extend_ref_kv_tuple() {
7040+
use std::ops::AddAssign;
7041+
let mut a = HashMap::new();
7042+
a.insert(0, 0);
7043+
7044+
fn create_arr<T: AddAssign<T> + Copy, const N: usize>(start: T, step: T) -> [(T, T); N] {
7045+
let mut outs: [(T, T); N] = [(start, start); N];
7046+
let mut element = step;
7047+
outs.iter_mut().skip(1).for_each(|(k, v)| {
7048+
*k += element;
7049+
*v += element;
7050+
element += step;
7051+
});
7052+
outs
7053+
}
7054+
7055+
let for_iter: Vec<_> = (0..100).map(|i| (i, i)).collect();
7056+
let iter = for_iter.iter();
7057+
let vec: Vec<_> = (100..200).map(|i| (i, i)).collect();
7058+
a.extend(iter);
7059+
a.extend(&vec);
7060+
a.extend(&create_arr::<i32, 100>(200, 1));
7061+
7062+
assert_eq!(a.len(), 300);
7063+
7064+
for item in 0..300 {
7065+
assert_eq!(a[&item], item);
7066+
}
7067+
}
7068+
69787069
#[test]
69797070
fn test_capacity_not_less_than_len() {
69807071
let mut a = HashMap::new();

0 commit comments

Comments
 (0)