133d722a9Sopenharmony_ciuse std::borrow::Borrow;
233d722a9Sopenharmony_ciuse std::hash::Hash;
333d722a9Sopenharmony_ciuse std::ops::Index;
433d722a9Sopenharmony_ciuse std::slice;
533d722a9Sopenharmony_ci
633d722a9Sopenharmony_cipub use self::ordered::OrderedMap;
733d722a9Sopenharmony_cipub use self::unordered::UnorderedMap;
833d722a9Sopenharmony_cipub use std::collections::hash_map::Entry;
933d722a9Sopenharmony_ci
1033d722a9Sopenharmony_cimod ordered {
1133d722a9Sopenharmony_ci    use super::{Entry, Iter, UnorderedMap};
1233d722a9Sopenharmony_ci    use std::borrow::Borrow;
1333d722a9Sopenharmony_ci    use std::hash::Hash;
1433d722a9Sopenharmony_ci    use std::mem;
1533d722a9Sopenharmony_ci
1633d722a9Sopenharmony_ci    pub struct OrderedMap<K, V> {
1733d722a9Sopenharmony_ci        map: UnorderedMap<K, usize>,
1833d722a9Sopenharmony_ci        vec: Vec<(K, V)>,
1933d722a9Sopenharmony_ci    }
2033d722a9Sopenharmony_ci
2133d722a9Sopenharmony_ci    impl<K, V> OrderedMap<K, V> {
2233d722a9Sopenharmony_ci        pub fn new() -> Self {
2333d722a9Sopenharmony_ci            OrderedMap {
2433d722a9Sopenharmony_ci                map: UnorderedMap::new(),
2533d722a9Sopenharmony_ci                vec: Vec::new(),
2633d722a9Sopenharmony_ci            }
2733d722a9Sopenharmony_ci        }
2833d722a9Sopenharmony_ci
2933d722a9Sopenharmony_ci        pub fn iter(&self) -> Iter<K, V> {
3033d722a9Sopenharmony_ci            Iter(self.vec.iter())
3133d722a9Sopenharmony_ci        }
3233d722a9Sopenharmony_ci
3333d722a9Sopenharmony_ci        pub fn keys(&self) -> impl Iterator<Item = &K> {
3433d722a9Sopenharmony_ci            self.vec.iter().map(|(k, _v)| k)
3533d722a9Sopenharmony_ci        }
3633d722a9Sopenharmony_ci    }
3733d722a9Sopenharmony_ci
3833d722a9Sopenharmony_ci    impl<K, V> OrderedMap<K, V>
3933d722a9Sopenharmony_ci    where
4033d722a9Sopenharmony_ci        K: Copy + Hash + Eq,
4133d722a9Sopenharmony_ci    {
4233d722a9Sopenharmony_ci        pub fn insert(&mut self, key: K, value: V) -> Option<V> {
4333d722a9Sopenharmony_ci            match self.map.entry(key) {
4433d722a9Sopenharmony_ci                Entry::Occupied(entry) => {
4533d722a9Sopenharmony_ci                    let i = &mut self.vec[*entry.get()];
4633d722a9Sopenharmony_ci                    Some(mem::replace(&mut i.1, value))
4733d722a9Sopenharmony_ci                }
4833d722a9Sopenharmony_ci                Entry::Vacant(entry) => {
4933d722a9Sopenharmony_ci                    entry.insert(self.vec.len());
5033d722a9Sopenharmony_ci                    self.vec.push((key, value));
5133d722a9Sopenharmony_ci                    None
5233d722a9Sopenharmony_ci                }
5333d722a9Sopenharmony_ci            }
5433d722a9Sopenharmony_ci        }
5533d722a9Sopenharmony_ci
5633d722a9Sopenharmony_ci        pub fn contains_key<Q>(&self, key: &Q) -> bool
5733d722a9Sopenharmony_ci        where
5833d722a9Sopenharmony_ci            K: Borrow<Q>,
5933d722a9Sopenharmony_ci            Q: ?Sized + Hash + Eq,
6033d722a9Sopenharmony_ci        {
6133d722a9Sopenharmony_ci            self.map.contains_key(key)
6233d722a9Sopenharmony_ci        }
6333d722a9Sopenharmony_ci
6433d722a9Sopenharmony_ci        pub fn get<Q>(&self, key: &Q) -> Option<&V>
6533d722a9Sopenharmony_ci        where
6633d722a9Sopenharmony_ci            K: Borrow<Q>,
6733d722a9Sopenharmony_ci            Q: ?Sized + Hash + Eq,
6833d722a9Sopenharmony_ci        {
6933d722a9Sopenharmony_ci            let i = *self.map.get(key)?;
7033d722a9Sopenharmony_ci            Some(&self.vec[i].1)
7133d722a9Sopenharmony_ci        }
7233d722a9Sopenharmony_ci    }
7333d722a9Sopenharmony_ci
7433d722a9Sopenharmony_ci    impl<'a, K, V> IntoIterator for &'a OrderedMap<K, V> {
7533d722a9Sopenharmony_ci        type Item = (&'a K, &'a V);
7633d722a9Sopenharmony_ci        type IntoIter = Iter<'a, K, V>;
7733d722a9Sopenharmony_ci        fn into_iter(self) -> Self::IntoIter {
7833d722a9Sopenharmony_ci            self.iter()
7933d722a9Sopenharmony_ci        }
8033d722a9Sopenharmony_ci    }
8133d722a9Sopenharmony_ci}
8233d722a9Sopenharmony_ci
8333d722a9Sopenharmony_cimod unordered {
8433d722a9Sopenharmony_ci    use crate::syntax::set::UnorderedSet;
8533d722a9Sopenharmony_ci    use std::borrow::Borrow;
8633d722a9Sopenharmony_ci    use std::collections::hash_map::{Entry, HashMap};
8733d722a9Sopenharmony_ci    use std::hash::Hash;
8833d722a9Sopenharmony_ci
8933d722a9Sopenharmony_ci    // Wrapper prohibits accidentally introducing iteration over the map, which
9033d722a9Sopenharmony_ci    // could lead to nondeterministic generated code.
9133d722a9Sopenharmony_ci    pub struct UnorderedMap<K, V>(HashMap<K, V>);
9233d722a9Sopenharmony_ci
9333d722a9Sopenharmony_ci    impl<K, V> UnorderedMap<K, V> {
9433d722a9Sopenharmony_ci        pub fn new() -> Self {
9533d722a9Sopenharmony_ci            UnorderedMap(HashMap::new())
9633d722a9Sopenharmony_ci        }
9733d722a9Sopenharmony_ci    }
9833d722a9Sopenharmony_ci
9933d722a9Sopenharmony_ci    impl<K, V> UnorderedMap<K, V>
10033d722a9Sopenharmony_ci    where
10133d722a9Sopenharmony_ci        K: Hash + Eq,
10233d722a9Sopenharmony_ci    {
10333d722a9Sopenharmony_ci        pub fn insert(&mut self, key: K, value: V) -> Option<V> {
10433d722a9Sopenharmony_ci            self.0.insert(key, value)
10533d722a9Sopenharmony_ci        }
10633d722a9Sopenharmony_ci
10733d722a9Sopenharmony_ci        pub fn contains_key<Q>(&self, key: &Q) -> bool
10833d722a9Sopenharmony_ci        where
10933d722a9Sopenharmony_ci            K: Borrow<Q>,
11033d722a9Sopenharmony_ci            Q: ?Sized + Hash + Eq,
11133d722a9Sopenharmony_ci        {
11233d722a9Sopenharmony_ci            self.0.contains_key(key)
11333d722a9Sopenharmony_ci        }
11433d722a9Sopenharmony_ci
11533d722a9Sopenharmony_ci        pub fn get<Q>(&self, key: &Q) -> Option<&V>
11633d722a9Sopenharmony_ci        where
11733d722a9Sopenharmony_ci            K: Borrow<Q>,
11833d722a9Sopenharmony_ci            Q: ?Sized + Hash + Eq,
11933d722a9Sopenharmony_ci        {
12033d722a9Sopenharmony_ci            self.0.get(key)
12133d722a9Sopenharmony_ci        }
12233d722a9Sopenharmony_ci
12333d722a9Sopenharmony_ci        pub fn entry(&mut self, key: K) -> Entry<K, V> {
12433d722a9Sopenharmony_ci            self.0.entry(key)
12533d722a9Sopenharmony_ci        }
12633d722a9Sopenharmony_ci
12733d722a9Sopenharmony_ci        #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
12833d722a9Sopenharmony_ci        pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
12933d722a9Sopenharmony_ci        where
13033d722a9Sopenharmony_ci            K: Borrow<Q>,
13133d722a9Sopenharmony_ci            Q: ?Sized + Hash + Eq,
13233d722a9Sopenharmony_ci        {
13333d722a9Sopenharmony_ci            self.0.remove(key)
13433d722a9Sopenharmony_ci        }
13533d722a9Sopenharmony_ci
13633d722a9Sopenharmony_ci        pub fn keys(&self) -> UnorderedSet<K>
13733d722a9Sopenharmony_ci        where
13833d722a9Sopenharmony_ci            K: Copy,
13933d722a9Sopenharmony_ci        {
14033d722a9Sopenharmony_ci            let mut set = UnorderedSet::new();
14133d722a9Sopenharmony_ci            for key in self.0.keys() {
14233d722a9Sopenharmony_ci                set.insert(*key);
14333d722a9Sopenharmony_ci            }
14433d722a9Sopenharmony_ci            set
14533d722a9Sopenharmony_ci        }
14633d722a9Sopenharmony_ci    }
14733d722a9Sopenharmony_ci}
14833d722a9Sopenharmony_ci
14933d722a9Sopenharmony_cipub struct Iter<'a, K, V>(slice::Iter<'a, (K, V)>);
15033d722a9Sopenharmony_ci
15133d722a9Sopenharmony_ciimpl<'a, K, V> Iterator for Iter<'a, K, V> {
15233d722a9Sopenharmony_ci    type Item = (&'a K, &'a V);
15333d722a9Sopenharmony_ci
15433d722a9Sopenharmony_ci    fn next(&mut self) -> Option<Self::Item> {
15533d722a9Sopenharmony_ci        let (k, v) = self.0.next()?;
15633d722a9Sopenharmony_ci        Some((k, v))
15733d722a9Sopenharmony_ci    }
15833d722a9Sopenharmony_ci
15933d722a9Sopenharmony_ci    fn size_hint(&self) -> (usize, Option<usize>) {
16033d722a9Sopenharmony_ci        self.0.size_hint()
16133d722a9Sopenharmony_ci    }
16233d722a9Sopenharmony_ci}
16333d722a9Sopenharmony_ci
16433d722a9Sopenharmony_ciimpl<K, V> Default for UnorderedMap<K, V> {
16533d722a9Sopenharmony_ci    fn default() -> Self {
16633d722a9Sopenharmony_ci        UnorderedMap::new()
16733d722a9Sopenharmony_ci    }
16833d722a9Sopenharmony_ci}
16933d722a9Sopenharmony_ci
17033d722a9Sopenharmony_ciimpl<Q, K, V> Index<&Q> for UnorderedMap<K, V>
17133d722a9Sopenharmony_ciwhere
17233d722a9Sopenharmony_ci    K: Borrow<Q> + Hash + Eq,
17333d722a9Sopenharmony_ci    Q: ?Sized + Hash + Eq,
17433d722a9Sopenharmony_ci{
17533d722a9Sopenharmony_ci    type Output = V;
17633d722a9Sopenharmony_ci
17733d722a9Sopenharmony_ci    fn index(&self, key: &Q) -> &V {
17833d722a9Sopenharmony_ci        self.get(key).unwrap()
17933d722a9Sopenharmony_ci    }
18033d722a9Sopenharmony_ci}
181