1 use std::borrow::Borrow;
2 use std::hash::Hash;
3 use std::ops::Index;
4 use std::slice;
5 
6 pub(crate) use self::ordered::OrderedMap;
7 pub(crate) use self::unordered::UnorderedMap;
8 pub(crate) use std::collections::hash_map::Entry;
9 
10 mod ordered {
11     use super::{Entry, Iter, UnorderedMap};
12     use std::borrow::Borrow;
13     use std::hash::Hash;
14     use std::mem;
15 
16     pub(crate) struct OrderedMap<K, V> {
17         map: UnorderedMap<K, usize>,
18         vec: Vec<(K, V)>,
19     }
20 
21     impl<K, V> OrderedMap<K, V> {
new() -> Self22         pub(crate) fn new() -> Self {
23             OrderedMap {
24                 map: UnorderedMap::new(),
25                 vec: Vec::new(),
26             }
27         }
28 
iter(&self) -> Iter<K, V>29         pub(crate) fn iter(&self) -> Iter<K, V> {
30             Iter(self.vec.iter())
31         }
32 
33         #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
keys(&self) -> impl Iterator<Item = &K>34         pub(crate) fn keys(&self) -> impl Iterator<Item = &K> {
35             self.vec.iter().map(|(k, _v)| k)
36         }
37     }
38 
39     impl<K, V> OrderedMap<K, V>
40     where
41         K: Copy + Hash + Eq,
42     {
insert(&mut self, key: K, value: V) -> Option<V>43         pub(crate) fn insert(&mut self, key: K, value: V) -> Option<V> {
44             match self.map.entry(key) {
45                 Entry::Occupied(entry) => {
46                     let i = &mut self.vec[*entry.get()];
47                     Some(mem::replace(&mut i.1, value))
48                 }
49                 Entry::Vacant(entry) => {
50                     entry.insert(self.vec.len());
51                     self.vec.push((key, value));
52                     None
53                 }
54             }
55         }
56 
contains_key<Q>(&self, key: &Q) -> bool where K: Borrow<Q>, Q: ?Sized + Hash + Eq,57         pub(crate) fn contains_key<Q>(&self, key: &Q) -> bool
58         where
59             K: Borrow<Q>,
60             Q: ?Sized + Hash + Eq,
61         {
62             self.map.contains_key(key)
63         }
64     }
65 
66     impl<'a, K, V> IntoIterator for &'a OrderedMap<K, V> {
67         type Item = (&'a K, &'a V);
68         type IntoIter = Iter<'a, K, V>;
into_iter(self) -> Self::IntoIter69         fn into_iter(self) -> Self::IntoIter {
70             self.iter()
71         }
72     }
73 }
74 
75 mod unordered {
76     use crate::syntax::set::UnorderedSet;
77     use std::borrow::Borrow;
78     use std::collections::hash_map::{Entry, HashMap};
79     use std::hash::Hash;
80 
81     // Wrapper prohibits accidentally introducing iteration over the map, which
82     // could lead to nondeterministic generated code.
83     pub(crate) struct UnorderedMap<K, V>(HashMap<K, V>);
84 
85     impl<K, V> UnorderedMap<K, V> {
new() -> Self86         pub(crate) fn new() -> Self {
87             UnorderedMap(HashMap::new())
88         }
89     }
90 
91     impl<K, V> UnorderedMap<K, V>
92     where
93         K: Hash + Eq,
94     {
insert(&mut self, key: K, value: V) -> Option<V>95         pub(crate) fn insert(&mut self, key: K, value: V) -> Option<V> {
96             self.0.insert(key, value)
97         }
98 
contains_key<Q>(&self, key: &Q) -> bool where K: Borrow<Q>, Q: ?Sized + Hash + Eq,99         pub(crate) fn contains_key<Q>(&self, key: &Q) -> bool
100         where
101             K: Borrow<Q>,
102             Q: ?Sized + Hash + Eq,
103         {
104             self.0.contains_key(key)
105         }
106 
get<Q>(&self, key: &Q) -> Option<&V> where K: Borrow<Q>, Q: ?Sized + Hash + Eq,107         pub(crate) fn get<Q>(&self, key: &Q) -> Option<&V>
108         where
109             K: Borrow<Q>,
110             Q: ?Sized + Hash + Eq,
111         {
112             self.0.get(key)
113         }
114 
entry(&mut self, key: K) -> Entry<K, V>115         pub(crate) fn entry(&mut self, key: K) -> Entry<K, V> {
116             self.0.entry(key)
117         }
118 
119         #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
remove<Q>(&mut self, key: &Q) -> Option<V> where K: Borrow<Q>, Q: ?Sized + Hash + Eq,120         pub(crate) fn remove<Q>(&mut self, key: &Q) -> Option<V>
121         where
122             K: Borrow<Q>,
123             Q: ?Sized + Hash + Eq,
124         {
125             self.0.remove(key)
126         }
127 
keys(&self) -> UnorderedSet<K> where K: Copy,128         pub(crate) fn keys(&self) -> UnorderedSet<K>
129         where
130             K: Copy,
131         {
132             let mut set = UnorderedSet::new();
133             for key in self.0.keys() {
134                 set.insert(*key);
135             }
136             set
137         }
138     }
139 }
140 
141 pub(crate) struct Iter<'a, K, V>(slice::Iter<'a, (K, V)>);
142 
143 impl<'a, K, V> Iterator for Iter<'a, K, V> {
144     type Item = (&'a K, &'a V);
145 
next(&mut self) -> Option<Self::Item>146     fn next(&mut self) -> Option<Self::Item> {
147         let (k, v) = self.0.next()?;
148         Some((k, v))
149     }
150 
size_hint(&self) -> (usize, Option<usize>)151     fn size_hint(&self) -> (usize, Option<usize>) {
152         self.0.size_hint()
153     }
154 }
155 
156 impl<K, V> Default for UnorderedMap<K, V> {
default() -> Self157     fn default() -> Self {
158         UnorderedMap::new()
159     }
160 }
161 
162 impl<Q, K, V> Index<&Q> for UnorderedMap<K, V>
163 where
164     K: Borrow<Q> + Hash + Eq,
165     Q: ?Sized + Hash + Eq,
166 {
167     type Output = V;
168 
index(&self, key: &Q) -> &V169     fn index(&self, key: &Q) -> &V {
170         self.get(key).unwrap()
171     }
172 }
173