cxx_build/syntax/
map.rs

1use std::borrow::Borrow;
2use std::hash::Hash;
3use std::ops::Index;
4
5pub(crate) use self::ordered::OrderedMap;
6pub(crate) use self::unordered::UnorderedMap;
7pub(crate) use std::collections::hash_map::Entry;
8
9mod ordered {
10    use std::hash::Hash;
11
12    pub(crate) struct OrderedMap<K, V>(indexmap::IndexMap<K, V>);
13
14    impl<K, V> OrderedMap<K, V> {
15        pub(crate) fn new() -> Self {
16            OrderedMap(indexmap::IndexMap::new())
17        }
18
19        #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
20        pub(crate) fn keys(&self) -> impl Iterator<Item = &K> {
21            self.0.keys()
22        }
23    }
24
25    impl<K, V> OrderedMap<K, V>
26    where
27        K: Hash + Eq,
28    {
29        pub(crate) fn insert(&mut self, key: K, value: V) -> Option<V> {
30            self.0.insert(key, value)
31        }
32
33        pub(crate) fn contains_key<Q>(&self, key: &Q) -> bool
34        where
35            Q: ?Sized + Hash + indexmap::Equivalent<K>,
36        {
37            self.0.contains_key(key)
38        }
39    }
40
41    impl<'a, K, V> IntoIterator for &'a OrderedMap<K, V> {
42        type Item = (&'a K, &'a V);
43        type IntoIter = indexmap::map::Iter<'a, K, V>;
44        fn into_iter(self) -> Self::IntoIter {
45            self.0.iter()
46        }
47    }
48}
49
50mod unordered {
51    use crate::syntax::set::UnorderedSet;
52    use std::borrow::Borrow;
53    use std::collections::hash_map::{Entry, HashMap};
54    use std::hash::Hash;
55
56    // Wrapper prohibits accidentally introducing iteration over the map, which
57    // could lead to nondeterministic generated code.
58    pub(crate) struct UnorderedMap<K, V>(HashMap<K, V>);
59
60    impl<K, V> UnorderedMap<K, V> {
61        pub(crate) fn new() -> Self {
62            UnorderedMap(HashMap::new())
63        }
64    }
65
66    impl<K, V> UnorderedMap<K, V>
67    where
68        K: Hash + Eq,
69    {
70        pub(crate) fn insert(&mut self, key: K, value: V) -> Option<V> {
71            self.0.insert(key, value)
72        }
73
74        pub(crate) fn contains_key<Q>(&self, key: &Q) -> bool
75        where
76            K: Borrow<Q>,
77            Q: ?Sized + Hash + Eq,
78        {
79            self.0.contains_key(key)
80        }
81
82        pub(crate) fn get<Q>(&self, key: &Q) -> Option<&V>
83        where
84            K: Borrow<Q>,
85            Q: ?Sized + Hash + Eq,
86        {
87            self.0.get(key)
88        }
89
90        pub(crate) fn entry(&mut self, key: K) -> Entry<K, V> {
91            self.0.entry(key)
92        }
93
94        #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
95        pub(crate) fn remove<Q>(&mut self, key: &Q) -> Option<V>
96        where
97            K: Borrow<Q>,
98            Q: ?Sized + Hash + Eq,
99        {
100            self.0.remove(key)
101        }
102
103        pub(crate) fn keys(&self) -> UnorderedSet<K>
104        where
105            K: Copy,
106        {
107            let mut set = UnorderedSet::new();
108            for key in self.0.keys() {
109                set.insert(*key);
110            }
111            set
112        }
113    }
114}
115
116impl<K, V> Default for UnorderedMap<K, V> {
117    fn default() -> Self {
118        UnorderedMap::new()
119    }
120}
121
122impl<Q, K, V> Index<&Q> for UnorderedMap<K, V>
123where
124    K: Borrow<Q> + Hash + Eq,
125    Q: ?Sized + Hash + Eq,
126{
127    type Output = V;
128
129    fn index(&self, key: &Q) -> &V {
130        self.get(key).unwrap()
131    }
132}