Skip to content

Commit 080edd9

Browse files
committed
Auto merge of #32633 - frewsxcv:map-values-mut, r=alexcrichton
Implement `values_mut` on `{BTree, Hash}Map` #32551
2 parents 5ab11d7 + 2084f2e commit 080edd9

File tree

5 files changed

+138
-0
lines changed

5 files changed

+138
-0
lines changed

src/libcollections/btree/map.rs

+60
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,12 @@ pub struct Values<'a, K: 'a, V: 'a> {
285285
inner: Iter<'a, K, V>,
286286
}
287287

288+
/// A mutable iterator over a BTreeMap's values.
289+
#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
290+
pub struct ValuesMut<'a, K: 'a, V: 'a> {
291+
inner: IterMut<'a, K, V>,
292+
}
293+
288294
/// An iterator over a sub-range of BTreeMap's entries.
289295
pub struct Range<'a, K: 'a, V: 'a> {
290296
front: Handle<NodeRef<marker::Immut<'a>, K, V, marker::Leaf>, marker::Edge>,
@@ -1006,6 +1012,33 @@ impl<'a, K, V> Iterator for Range<'a, K, V> {
10061012
}
10071013
}
10081014

1015+
#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
1016+
impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
1017+
type Item = &'a mut V;
1018+
1019+
fn next(&mut self) -> Option<&'a mut V> {
1020+
self.inner.next().map(|(_, v)| v)
1021+
}
1022+
1023+
fn size_hint(&self) -> (usize, Option<usize>) {
1024+
self.inner.size_hint()
1025+
}
1026+
}
1027+
1028+
#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
1029+
impl<'a, K, V> DoubleEndedIterator for ValuesMut<'a, K, V> {
1030+
fn next_back(&mut self) -> Option<&'a mut V> {
1031+
self.inner.next_back().map(|(_, v)| v)
1032+
}
1033+
}
1034+
1035+
#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
1036+
impl<'a, K, V> ExactSizeIterator for ValuesMut<'a, K, V> {
1037+
fn len(&self) -> usize {
1038+
self.inner.len()
1039+
}
1040+
}
1041+
10091042
impl<'a, K, V> Range<'a, K, V> {
10101043
unsafe fn next_unchecked(&mut self) -> (&'a K, &'a V) {
10111044
let handle = self.front;
@@ -1403,6 +1436,33 @@ impl<K, V> BTreeMap<K, V> {
14031436
Values { inner: self.iter() }
14041437
}
14051438

1439+
/// Gets a mutable iterator over the values of the map, in order by key.
1440+
///
1441+
/// # Examples
1442+
///
1443+
/// Basic usage:
1444+
///
1445+
/// ```
1446+
/// # #![feature(map_values_mut)]
1447+
/// use std::collections::BTreeMap;
1448+
///
1449+
/// let mut a = BTreeMap::new();
1450+
/// a.insert(1, String::from("hello"));
1451+
/// a.insert(2, String::from("goodbye"));
1452+
///
1453+
/// for value in a.values_mut() {
1454+
/// value.push_str("!");
1455+
/// }
1456+
///
1457+
/// let values: Vec<String> = a.values().cloned().collect();
1458+
/// assert_eq!(values, [String::from("hello!"),
1459+
/// String::from("goodbye!")]);
1460+
/// ```
1461+
#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
1462+
pub fn values_mut<'a>(&'a mut self) -> ValuesMut<'a, K, V> {
1463+
ValuesMut { inner: self.iter_mut() }
1464+
}
1465+
14061466
/// Returns the number of elements in the map.
14071467
///
14081468
/// # Examples

src/libcollectionstest/btree/map.rs

+15
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,21 @@ fn test_iter_rev() {
114114
test(size, map.into_iter().rev());
115115
}
116116

117+
#[test]
118+
fn test_values_mut() {
119+
let mut a = BTreeMap::new();
120+
a.insert(1, String::from("hello"));
121+
a.insert(2, String::from("goodbye"));
122+
123+
for value in a.values_mut() {
124+
value.push_str("!");
125+
}
126+
127+
let values: Vec<String> = a.values().cloned().collect();
128+
assert_eq!(values, [String::from("hello!"),
129+
String::from("goodbye!")]);
130+
}
131+
117132
#[test]
118133
fn test_iter_mixed() {
119134
let size = 10000;

src/libcollectionstest/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#![feature(enumset)]
2323
#![feature(iter_arith)]
2424
#![feature(map_entry_keys)]
25+
#![feature(map_values_mut)]
2526
#![feature(pattern)]
2627
#![feature(rand)]
2728
#![feature(set_recovery)]

src/libstd/collections/hash/map.rs

+61
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,34 @@ impl<K, V, S> HashMap<K, V, S>
861861
Values { inner: self.iter() }
862862
}
863863

864+
/// An iterator visiting all values mutably in arbitrary order.
865+
/// Iterator element type is `&'a mut V`.
866+
///
867+
/// # Examples
868+
///
869+
/// ```
870+
/// # #![feature(map_values_mut)]
871+
/// use std::collections::HashMap;
872+
///
873+
/// let mut map = HashMap::new();
874+
///
875+
/// map.insert("a", 1);
876+
/// map.insert("b", 2);
877+
/// map.insert("c", 3);
878+
///
879+
/// for val in map.values_mut() {
880+
/// *val = *val + 10;
881+
/// }
882+
///
883+
/// for val in map.values() {
884+
/// print!("{}", val);
885+
/// }
886+
/// ```
887+
#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
888+
pub fn values_mut<'a>(&'a mut self) -> ValuesMut<'a, K, V> {
889+
ValuesMut { inner: self.iter_mut() }
890+
}
891+
864892
/// An iterator visiting all key-value pairs in arbitrary order.
865893
/// Iterator element type is `(&'a K, &'a V)`.
866894
///
@@ -1262,6 +1290,12 @@ pub struct Drain<'a, K: 'a, V: 'a> {
12621290
inner: table::Drain<'a, K, V>
12631291
}
12641292

1293+
/// Mutable HashMap values iterator.
1294+
#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
1295+
pub struct ValuesMut<'a, K: 'a, V: 'a> {
1296+
inner: IterMut<'a, K, V>
1297+
}
1298+
12651299
enum InternalEntry<K, V, M> {
12661300
Occupied {
12671301
elem: FullBucket<K, V, M>,
@@ -1460,6 +1494,18 @@ impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {
14601494
#[inline] fn len(&self) -> usize { self.inner.len() }
14611495
}
14621496

1497+
#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
1498+
impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
1499+
type Item = &'a mut V;
1500+
1501+
#[inline] fn next(&mut self) -> Option<(&'a mut V)> { self.inner.next().map(|(_, v)| v) }
1502+
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
1503+
}
1504+
#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
1505+
impl<'a, K, V> ExactSizeIterator for ValuesMut<'a, K, V> {
1506+
#[inline] fn len(&self) -> usize { self.inner.len() }
1507+
}
1508+
14631509
#[stable(feature = "rust1", since = "1.0.0")]
14641510
impl<'a, K, V> Iterator for Drain<'a, K, V> {
14651511
type Item = (K, V);
@@ -1907,6 +1953,7 @@ mod test_map {
19071953
assert_eq!(m.drain().next(), None);
19081954
assert_eq!(m.keys().next(), None);
19091955
assert_eq!(m.values().next(), None);
1956+
assert_eq!(m.values_mut().next(), None);
19101957
assert_eq!(m.iter().next(), None);
19111958
assert_eq!(m.iter_mut().next(), None);
19121959
assert_eq!(m.len(), 0);
@@ -2083,6 +2130,20 @@ mod test_map {
20832130
assert!(values.contains(&'c'));
20842131
}
20852132

2133+
#[test]
2134+
fn test_values_mut() {
2135+
let vec = vec![(1, 1), (2, 2), (3, 3)];
2136+
let mut map: HashMap<_, _> = vec.into_iter().collect();
2137+
for value in map.values_mut() {
2138+
*value = (*value) * 2
2139+
}
2140+
let values: Vec<_> = map.values().cloned().collect();
2141+
assert_eq!(values.len(), 3);
2142+
assert!(values.contains(&2));
2143+
assert!(values.contains(&4));
2144+
assert!(values.contains(&6));
2145+
}
2146+
20862147
#[test]
20872148
fn test_find() {
20882149
let mut m = HashMap::new();

src/libstd/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@
241241
#![feature(link_args)]
242242
#![feature(linkage)]
243243
#![feature(macro_reexport)]
244+
#![cfg_attr(test, feature(map_values_mut))]
244245
#![feature(num_bits_bytes)]
245246
#![feature(old_wrapping)]
246247
#![feature(on_unimplemented)]

0 commit comments

Comments
 (0)