Skip to content

Commit 1facd4a

Browse files
committed
Auto merge of #75163 - canova:map_into_keys_values, r=dtolnay
Implement `into_keys` and `into_values` for associative maps This PR implements `into_keys` and `into_values` for HashMap and BTreeMap types. They are implemented as unstable, under `map_into_keys_values` feature. Fixes #55214. r? @dtolnay
2 parents 3f091ba + 4cd2637 commit 1facd4a

File tree

4 files changed

+325
-0
lines changed

4 files changed

+325
-0
lines changed

library/alloc/src/collections/btree/map.rs

+148
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// ignore-tidy-filelength
2+
13
use core::borrow::Borrow;
24
use core::cmp::Ordering;
35
use core::fmt::Debug;
@@ -355,6 +357,30 @@ pub struct ValuesMut<'a, K: 'a, V: 'a> {
355357
inner: IterMut<'a, K, V>,
356358
}
357359

360+
/// An owning iterator over the keys of a `BTreeMap`.
361+
///
362+
/// This `struct` is created by the [`into_keys`] method on [`BTreeMap`].
363+
/// See its documentation for more.
364+
///
365+
/// [`into_keys`]: BTreeMap::into_keys
366+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
367+
#[derive(Debug)]
368+
pub struct IntoKeys<K, V> {
369+
inner: IntoIter<K, V>,
370+
}
371+
372+
/// An owning iterator over the values of a `BTreeMap`.
373+
///
374+
/// This `struct` is created by the [`into_values`] method on [`BTreeMap`].
375+
/// See its documentation for more.
376+
///
377+
/// [`into_values`]: BTreeMap::into_values
378+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
379+
#[derive(Debug)]
380+
pub struct IntoValues<K, V> {
381+
inner: IntoIter<K, V>,
382+
}
383+
358384
/// An iterator over a sub-range of entries in a `BTreeMap`.
359385
///
360386
/// This `struct` is created by the [`range`] method on [`BTreeMap`]. See its
@@ -1291,6 +1317,52 @@ impl<K: Ord, V> BTreeMap<K, V> {
12911317

12921318
self.length = dfs(self.root.as_ref().unwrap().as_ref());
12931319
}
1320+
1321+
/// Creates a consuming iterator visiting all the keys, in sorted order.
1322+
/// The map cannot be used after calling this.
1323+
/// The iterator element type is `K`.
1324+
///
1325+
/// # Examples
1326+
///
1327+
/// ```
1328+
/// #![feature(map_into_keys_values)]
1329+
/// use std::collections::BTreeMap;
1330+
///
1331+
/// let mut a = BTreeMap::new();
1332+
/// a.insert(2, "b");
1333+
/// a.insert(1, "a");
1334+
///
1335+
/// let keys: Vec<i32> = a.into_keys().collect();
1336+
/// assert_eq!(keys, [1, 2]);
1337+
/// ```
1338+
#[inline]
1339+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1340+
pub fn into_keys(self) -> IntoKeys<K, V> {
1341+
IntoKeys { inner: self.into_iter() }
1342+
}
1343+
1344+
/// Creates a consuming iterator visiting all the values, in order by key.
1345+
/// The map cannot be used after calling this.
1346+
/// The iterator element type is `V`.
1347+
///
1348+
/// # Examples
1349+
///
1350+
/// ```
1351+
/// #![feature(map_into_keys_values)]
1352+
/// use std::collections::BTreeMap;
1353+
///
1354+
/// let mut a = BTreeMap::new();
1355+
/// a.insert(1, "hello");
1356+
/// a.insert(2, "goodbye");
1357+
///
1358+
/// let values: Vec<&str> = a.into_values().collect();
1359+
/// assert_eq!(values, ["hello", "goodbye"]);
1360+
/// ```
1361+
#[inline]
1362+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1363+
pub fn into_values(self) -> IntoValues<K, V> {
1364+
IntoValues { inner: self.into_iter() }
1365+
}
12941366
}
12951367

12961368
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1780,6 +1852,82 @@ impl<'a, K, V> Range<'a, K, V> {
17801852
}
17811853
}
17821854

1855+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1856+
impl<K, V> Iterator for IntoKeys<K, V> {
1857+
type Item = K;
1858+
1859+
fn next(&mut self) -> Option<K> {
1860+
self.inner.next().map(|(k, _)| k)
1861+
}
1862+
1863+
fn size_hint(&self) -> (usize, Option<usize>) {
1864+
self.inner.size_hint()
1865+
}
1866+
1867+
fn last(mut self) -> Option<K> {
1868+
self.next_back()
1869+
}
1870+
1871+
fn min(mut self) -> Option<K> {
1872+
self.next()
1873+
}
1874+
1875+
fn max(mut self) -> Option<K> {
1876+
self.next_back()
1877+
}
1878+
}
1879+
1880+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1881+
impl<K, V> DoubleEndedIterator for IntoKeys<K, V> {
1882+
fn next_back(&mut self) -> Option<K> {
1883+
self.inner.next_back().map(|(k, _)| k)
1884+
}
1885+
}
1886+
1887+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1888+
impl<K, V> ExactSizeIterator for IntoKeys<K, V> {
1889+
fn len(&self) -> usize {
1890+
self.inner.len()
1891+
}
1892+
}
1893+
1894+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1895+
impl<K, V> FusedIterator for IntoKeys<K, V> {}
1896+
1897+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1898+
impl<K, V> Iterator for IntoValues<K, V> {
1899+
type Item = V;
1900+
1901+
fn next(&mut self) -> Option<V> {
1902+
self.inner.next().map(|(_, v)| v)
1903+
}
1904+
1905+
fn size_hint(&self) -> (usize, Option<usize>) {
1906+
self.inner.size_hint()
1907+
}
1908+
1909+
fn last(mut self) -> Option<V> {
1910+
self.next_back()
1911+
}
1912+
}
1913+
1914+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1915+
impl<K, V> DoubleEndedIterator for IntoValues<K, V> {
1916+
fn next_back(&mut self) -> Option<V> {
1917+
self.inner.next_back().map(|(_, v)| v)
1918+
}
1919+
}
1920+
1921+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1922+
impl<K, V> ExactSizeIterator for IntoValues<K, V> {
1923+
fn len(&self) -> usize {
1924+
self.inner.len()
1925+
}
1926+
}
1927+
1928+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1929+
impl<K, V> FusedIterator for IntoValues<K, V> {}
1930+
17831931
#[stable(feature = "btree_range", since = "1.17.0")]
17841932
impl<'a, K, V> DoubleEndedIterator for Range<'a, K, V> {
17851933
fn next_back(&mut self) -> Option<(&'a K, &'a V)> {

library/alloc/tests/btree/map.rs

+24
Original file line numberDiff line numberDiff line change
@@ -1461,3 +1461,27 @@ fn test_into_iter_drop_leak_height_1() {
14611461
assert_eq!(DROPS.load(Ordering::SeqCst), size);
14621462
}
14631463
}
1464+
1465+
#[test]
1466+
fn test_into_keys() {
1467+
let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
1468+
let map: BTreeMap<_, _> = vec.into_iter().collect();
1469+
let keys: Vec<_> = map.into_keys().collect();
1470+
1471+
assert_eq!(keys.len(), 3);
1472+
assert!(keys.contains(&1));
1473+
assert!(keys.contains(&2));
1474+
assert!(keys.contains(&3));
1475+
}
1476+
1477+
#[test]
1478+
fn test_into_values() {
1479+
let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
1480+
let map: BTreeMap<_, _> = vec.into_iter().collect();
1481+
let values: Vec<_> = map.into_values().collect();
1482+
1483+
assert_eq!(values.len(), 3);
1484+
assert!(values.contains(&'a'));
1485+
assert!(values.contains(&'b'));
1486+
assert!(values.contains(&'c'));
1487+
}

library/alloc/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#![feature(drain_filter)]
55
#![feature(exact_size_is_empty)]
66
#![feature(map_first_last)]
7+
#![feature(map_into_keys_values)]
78
#![feature(new_uninit)]
89
#![feature(pattern)]
910
#![feature(str_split_once)]

library/std/src/collections/hash/map.rs

+152
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,52 @@ where
872872
{
873873
self.base.retain(f)
874874
}
875+
876+
/// Creates a consuming iterator visiting all the keys in arbitrary order.
877+
/// The map cannot be used after calling this.
878+
/// The iterator element type is `K`.
879+
///
880+
/// # Examples
881+
///
882+
/// ```
883+
/// #![feature(map_into_keys_values)]
884+
/// use std::collections::HashMap;
885+
///
886+
/// let mut map = HashMap::new();
887+
/// map.insert("a", 1);
888+
/// map.insert("b", 2);
889+
/// map.insert("c", 3);
890+
///
891+
/// let vec: Vec<&str> = map.into_keys().collect();
892+
/// ```
893+
#[inline]
894+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
895+
pub fn into_keys(self) -> IntoKeys<K, V> {
896+
IntoKeys { inner: self.into_iter() }
897+
}
898+
899+
/// Creates a consuming iterator visiting all the values in arbitrary order.
900+
/// The map cannot be used after calling this.
901+
/// The iterator element type is `V`.
902+
///
903+
/// # Examples
904+
///
905+
/// ```
906+
/// #![feature(map_into_keys_values)]
907+
/// use std::collections::HashMap;
908+
///
909+
/// let mut map = HashMap::new();
910+
/// map.insert("a", 1);
911+
/// map.insert("b", 2);
912+
/// map.insert("c", 3);
913+
///
914+
/// let vec: Vec<i32> = map.into_values().collect();
915+
/// ```
916+
#[inline]
917+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
918+
pub fn into_values(self) -> IntoValues<K, V> {
919+
IntoValues { inner: self.into_iter() }
920+
}
875921
}
876922

877923
impl<K, V, S> HashMap<K, V, S>
@@ -1154,6 +1200,28 @@ pub struct ValuesMut<'a, K: 'a, V: 'a> {
11541200
inner: IterMut<'a, K, V>,
11551201
}
11561202

1203+
/// An owning iterator over the keys of a `HashMap`.
1204+
///
1205+
/// This `struct` is created by the [`into_keys`] method on [`HashMap`].
1206+
/// See its documentation for more.
1207+
///
1208+
/// [`into_keys`]: HashMap::into_keys
1209+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1210+
pub struct IntoKeys<K, V> {
1211+
inner: IntoIter<K, V>,
1212+
}
1213+
1214+
/// An owning iterator over the values of a `HashMap`.
1215+
///
1216+
/// This `struct` is created by the [`into_values`] method on [`HashMap`].
1217+
/// See its documentation for more.
1218+
///
1219+
/// [`into_values`]: HashMap::into_values
1220+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1221+
pub struct IntoValues<K, V> {
1222+
inner: IntoIter<K, V>,
1223+
}
1224+
11571225
/// A builder for computing where in a HashMap a key-value pair would be stored.
11581226
///
11591227
/// See the [`HashMap::raw_entry_mut`] docs for usage examples.
@@ -1827,6 +1895,66 @@ where
18271895
}
18281896
}
18291897

1898+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1899+
impl<K, V> Iterator for IntoKeys<K, V> {
1900+
type Item = K;
1901+
1902+
#[inline]
1903+
fn next(&mut self) -> Option<K> {
1904+
self.inner.next().map(|(k, _)| k)
1905+
}
1906+
#[inline]
1907+
fn size_hint(&self) -> (usize, Option<usize>) {
1908+
self.inner.size_hint()
1909+
}
1910+
}
1911+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1912+
impl<K, V> ExactSizeIterator for IntoKeys<K, V> {
1913+
#[inline]
1914+
fn len(&self) -> usize {
1915+
self.inner.len()
1916+
}
1917+
}
1918+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1919+
impl<K, V> FusedIterator for IntoKeys<K, V> {}
1920+
1921+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1922+
impl<K: Debug, V: Debug> fmt::Debug for IntoKeys<K, V> {
1923+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1924+
f.debug_list().entries(self.inner.iter().map(|(k, _)| k)).finish()
1925+
}
1926+
}
1927+
1928+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1929+
impl<K, V> Iterator for IntoValues<K, V> {
1930+
type Item = V;
1931+
1932+
#[inline]
1933+
fn next(&mut self) -> Option<V> {
1934+
self.inner.next().map(|(_, v)| v)
1935+
}
1936+
#[inline]
1937+
fn size_hint(&self) -> (usize, Option<usize>) {
1938+
self.inner.size_hint()
1939+
}
1940+
}
1941+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1942+
impl<K, V> ExactSizeIterator for IntoValues<K, V> {
1943+
#[inline]
1944+
fn len(&self) -> usize {
1945+
self.inner.len()
1946+
}
1947+
}
1948+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1949+
impl<K, V> FusedIterator for IntoValues<K, V> {}
1950+
1951+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
1952+
impl<K: Debug, V: Debug> fmt::Debug for IntoValues<K, V> {
1953+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1954+
f.debug_list().entries(self.inner.iter().map(|(_, v)| v)).finish()
1955+
}
1956+
}
1957+
18301958
#[stable(feature = "drain", since = "1.6.0")]
18311959
impl<'a, K, V> Iterator for Drain<'a, K, V> {
18321960
type Item = (K, V);
@@ -3084,6 +3212,30 @@ mod test_map {
30843212
assert!(values.contains(&6));
30853213
}
30863214

3215+
#[test]
3216+
fn test_into_keys() {
3217+
let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
3218+
let map: HashMap<_, _> = vec.into_iter().collect();
3219+
let keys: Vec<_> = map.into_keys().collect();
3220+
3221+
assert_eq!(keys.len(), 3);
3222+
assert!(keys.contains(&1));
3223+
assert!(keys.contains(&2));
3224+
assert!(keys.contains(&3));
3225+
}
3226+
3227+
#[test]
3228+
fn test_into_values() {
3229+
let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
3230+
let map: HashMap<_, _> = vec.into_iter().collect();
3231+
let values: Vec<_> = map.into_values().collect();
3232+
3233+
assert_eq!(values.len(), 3);
3234+
assert!(values.contains(&'a'));
3235+
assert!(values.contains(&'b'));
3236+
assert!(values.contains(&'c'));
3237+
}
3238+
30873239
#[test]
30883240
fn test_find() {
30893241
let mut m = HashMap::new();

0 commit comments

Comments
 (0)