Skip to content

Commit aa7024b

Browse files
committed
Add VecMap to rustc_data_structures
1 parent 022720b commit aa7024b

File tree

3 files changed

+186
-0
lines changed

3 files changed

+186
-0
lines changed

compiler/rustc_data_structures/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ pub mod thin_vec;
9696
pub mod tiny_list;
9797
pub mod transitive_relation;
9898
pub mod vec_linked_list;
99+
pub mod vec_map;
99100
pub mod work_queue;
100101
pub use atomic_ref::AtomicRef;
101102
pub mod frozen;
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
use std::borrow::Borrow;
2+
use std::iter::FromIterator;
3+
use std::slice::{Iter, IterMut};
4+
use std::vec::IntoIter;
5+
6+
use crate::stable_hasher::{HashStable, StableHasher};
7+
8+
#[derive(Clone, Encodable, Decodable, Debug)]
9+
pub struct VecMap<K, V>(Vec<(K, V)>);
10+
11+
impl<K, V> VecMap<K, V>
12+
where
13+
K: PartialEq,
14+
{
15+
pub fn new() -> Self {
16+
VecMap(Default::default())
17+
}
18+
19+
pub fn insert(&mut self, k: K, v: V) -> Option<V> {
20+
if let Some(elem) = self.0.iter_mut().find(|(key, _)| *key == k) {
21+
Some(std::mem::replace(&mut elem.1, v))
22+
} else {
23+
self.0.push((k, v));
24+
None
25+
}
26+
}
27+
28+
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
29+
where
30+
K: Borrow<Q>,
31+
Q: Eq,
32+
{
33+
self.0.iter().find(|(key, _)| k == key.borrow()).map(|elem| &elem.1)
34+
}
35+
36+
pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
37+
where
38+
K: Borrow<Q>,
39+
Q: Eq,
40+
{
41+
self.get(k).is_some()
42+
}
43+
44+
pub fn is_empty(&self) -> bool {
45+
self.0.is_empty()
46+
}
47+
48+
pub fn iter(&self) -> Iter<'_, (K, V)> {
49+
self.into_iter()
50+
}
51+
52+
pub fn iter_mut(&mut self) -> IterMut<'_, (K, V)> {
53+
self.into_iter()
54+
}
55+
}
56+
57+
impl<K, V> Default for VecMap<K, V> {
58+
#[inline]
59+
fn default() -> Self {
60+
Self(Default::default())
61+
}
62+
}
63+
64+
impl<K, V> From<Vec<(K, V)>> for VecMap<K, V> {
65+
fn from(vec: Vec<(K, V)>) -> Self {
66+
Self(vec)
67+
}
68+
}
69+
70+
impl<K, V> Into<Vec<(K, V)>> for VecMap<K, V> {
71+
fn into(self) -> Vec<(K, V)> {
72+
self.0
73+
}
74+
}
75+
76+
impl<K, V> FromIterator<(K, V)> for VecMap<K, V> {
77+
fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
78+
Self(iter.into_iter().collect())
79+
}
80+
}
81+
82+
impl<'a, K, V> IntoIterator for &'a VecMap<K, V> {
83+
type Item = &'a (K, V);
84+
type IntoIter = Iter<'a, (K, V)>;
85+
86+
#[inline]
87+
fn into_iter(self) -> Self::IntoIter {
88+
self.0.iter()
89+
}
90+
}
91+
92+
impl<'a, K, V> IntoIterator for &'a mut VecMap<K, V> {
93+
type Item = &'a mut (K, V);
94+
type IntoIter = IterMut<'a, (K, V)>;
95+
96+
#[inline]
97+
fn into_iter(self) -> Self::IntoIter {
98+
self.0.iter_mut()
99+
}
100+
}
101+
102+
impl<K, V> IntoIterator for VecMap<K, V> {
103+
type Item = (K, V);
104+
type IntoIter = IntoIter<(K, V)>;
105+
106+
#[inline]
107+
fn into_iter(self) -> Self::IntoIter {
108+
self.0.into_iter()
109+
}
110+
}
111+
112+
impl<K, V> Extend<(K, V)> for VecMap<K, V> {
113+
fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
114+
self.0.extend(iter);
115+
}
116+
117+
fn extend_one(&mut self, item: (K, V)) {
118+
self.0.extend_one(item);
119+
}
120+
121+
fn extend_reserve(&mut self, additional: usize) {
122+
self.0.extend_reserve(additional);
123+
}
124+
}
125+
126+
impl<K, V, CTX> HashStable<CTX> for VecMap<K, V>
127+
where
128+
K: HashStable<CTX> + Eq,
129+
V: HashStable<CTX>,
130+
{
131+
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
132+
self.0.hash_stable(hcx, hasher)
133+
}
134+
}
135+
136+
#[cfg(test)]
137+
mod tests;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use super::*;
2+
3+
impl<K, V> VecMap<K, V> {
4+
fn into_vec(self) -> Vec<(K, V)> {
5+
self.0.into()
6+
}
7+
}
8+
9+
#[test]
10+
fn test_from_iterator() {
11+
assert_eq!(
12+
std::iter::empty().collect::<VecMap<i32, bool>>().into_vec(),
13+
Vec::<(i32, bool)>::new()
14+
);
15+
assert_eq!(std::iter::once((42, true)).collect::<VecMap<_, _>>().into_vec(), vec![(42, true)]);
16+
assert_eq!(
17+
vec![(1, true), (2, false)].into_iter().collect::<VecMap<_, _>>().into_vec(),
18+
vec![(1, true), (2, false)]
19+
);
20+
}
21+
22+
#[test]
23+
fn test_into_iterator_owned() {
24+
assert_eq!(VecMap::new().into_iter().collect::<Vec<(i32, bool)>>(), Vec::<(i32, bool)>::new());
25+
assert_eq!(VecMap::from(vec![(1, true)]).into_iter().collect::<Vec<_>>(), vec![(1, true)]);
26+
assert_eq!(
27+
VecMap::from(vec![(1, true), (2, false)]).into_iter().collect::<Vec<_>>(),
28+
vec![(1, true), (2, false)]
29+
);
30+
}
31+
32+
#[test]
33+
fn test_insert() {
34+
let mut v = VecMap::new();
35+
assert_eq!(v.insert(1, true), None);
36+
assert_eq!(v.insert(2, false), None);
37+
assert_eq!(v.clone().into_vec(), vec![(1, true), (2, false)]);
38+
assert_eq!(v.insert(1, false), Some(true));
39+
assert_eq!(v.into_vec(), vec![(1, false), (2, false)]);
40+
}
41+
42+
#[test]
43+
fn test_get() {
44+
let v = vec![(1, true), (2, false)].into_iter().collect::<VecMap<_, _>>();
45+
assert_eq!(v.get(&1), Some(&true));
46+
assert_eq!(v.get(&2), Some(&false));
47+
assert_eq!(v.get(&3), None);
48+
}

0 commit comments

Comments
 (0)