wasmtime_environ/collections/
hash_map.rs1use crate::error::OutOfMemory;
2use core::{
3 borrow::Borrow,
4 fmt,
5 hash::{BuildHasher, Hash},
6 mem,
7};
8
9#[cfg(feature = "std")]
10use std::{collections::hash_map as inner, hash::RandomState as DefaultHashBuilder};
11
12#[cfg(not(feature = "std"))]
13use hashbrown::{DefaultHashBuilder, hash_map as inner};
14use wasmtime_core::alloc::TryClone;
15
16pub struct HashMap<K, V, S = DefaultHashBuilder> {
19 inner: inner::HashMap<K, V, S>,
20}
21
22impl<K, V, S> TryClone for HashMap<K, V, S>
23where
24 K: Eq + Hash + TryClone,
25 V: TryClone,
26 S: BuildHasher + TryClone,
27{
28 fn try_clone(&self) -> Result<Self, OutOfMemory> {
29 let mut map = Self::with_capacity_and_hasher(self.len(), self.hasher().try_clone()?)?;
30 for (k, v) in self {
31 map.insert(k.try_clone()?, v.try_clone()?)
32 .expect("reserved capacity");
33 }
34 Ok(map)
35 }
36}
37
38impl<K, V, S> Default for HashMap<K, V, S>
39where
40 S: Default,
41{
42 fn default() -> Self {
43 Self {
44 inner: inner::HashMap::default(),
45 }
46 }
47}
48
49impl<K, V, S> PartialEq for HashMap<K, V, S>
50where
51 K: Eq + Hash,
52 V: PartialEq,
53 S: BuildHasher,
54{
55 fn eq(&self, other: &Self) -> bool {
56 self.inner.eq(&other.inner)
57 }
58}
59
60impl<K, V, S> Eq for HashMap<K, V, S>
61where
62 K: Eq + Hash,
63 V: Eq,
64 S: BuildHasher,
65{
66}
67
68impl<K, V, S> fmt::Debug for HashMap<K, V, S>
69where
70 K: fmt::Debug,
71 V: fmt::Debug,
72{
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 fmt::Debug::fmt(&self.inner, f)
75 }
76}
77
78impl<K, V> HashMap<K, V, DefaultHashBuilder> {
79 pub fn new() -> Self {
81 Self {
82 inner: inner::HashMap::new(),
83 }
84 }
85}
86
87impl<K, V> HashMap<K, V, DefaultHashBuilder>
88where
89 K: Eq + Hash,
90{
91 pub fn with_capacity(capacity: usize) -> Result<Self, OutOfMemory> {
94 let mut map = Self::new();
95 map.reserve(capacity)?;
96 Ok(map)
97 }
98}
99
100impl<K, V, S> HashMap<K, V, S> {
101 pub const fn with_hasher(hasher: S) -> Self {
103 Self {
104 inner: inner::HashMap::with_hasher(hasher),
105 }
106 }
107
108 pub fn hasher(&self) -> &S {
110 self.inner.hasher()
111 }
112
113 pub fn capacity(&self) -> usize {
115 self.inner.capacity()
116 }
117
118 pub fn len(&self) -> usize {
120 self.inner.len()
121 }
122
123 pub fn is_empty(&self) -> bool {
125 self.inner.is_empty()
126 }
127
128 pub fn drain(&mut self) -> inner::Drain<'_, K, V> {
130 self.inner.drain()
131 }
132
133 pub fn retain<F>(&mut self, f: F)
135 where
136 F: FnMut(&K, &mut V) -> bool,
137 {
138 self.inner.retain(f);
139 }
140
141 pub fn extract_if<F>(&mut self, f: F) -> inner::ExtractIf<'_, K, V, F>
143 where
144 F: FnMut(&K, &mut V) -> bool,
145 {
146 self.inner.extract_if(f)
147 }
148
149 pub fn clear(&mut self) {
151 self.inner.clear();
152 }
153
154 pub fn iter(&self) -> inner::Iter<'_, K, V> {
156 self.inner.iter()
157 }
158
159 pub fn iter_mut(&mut self) -> inner::IterMut<'_, K, V> {
161 self.inner.iter_mut()
162 }
163}
164
165impl<K, V, S> HashMap<K, V, S>
166where
167 K: Eq + Hash,
168 S: BuildHasher,
169{
170 pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Result<Self, OutOfMemory> {
173 let mut map = Self::with_hasher(hasher);
174 map.reserve(capacity)?;
175 Ok(map)
176 }
177
178 pub fn reserve(&mut self, additional: usize) -> Result<(), OutOfMemory> {
181 self.inner.try_reserve(additional).map_err(|_| {
182 let new_len = self.len().saturating_add(additional);
183 OutOfMemory::new(
184 new_len
185 .saturating_mul(mem::size_of::<K>())
186 .saturating_add(new_len.saturating_mul(mem::size_of::<V>())),
187 )
188 })
189 }
190
191 pub fn contains_key<Q>(&self, key: &Q) -> bool
193 where
194 Q: Hash + Eq + ?Sized,
195 K: Borrow<Q>,
196 {
197 self.inner.contains_key(key)
198 }
199
200 pub fn get<Q>(&self, value: &Q) -> Option<&V>
202 where
203 Q: Hash + Eq + ?Sized,
204 K: Borrow<Q>,
205 {
206 self.inner.get(value)
207 }
208
209 pub fn insert(&mut self, key: K, value: V) -> Result<Option<V>, OutOfMemory> {
212 self.reserve(1)?;
213 Ok(self.inner.insert(key, value))
214 }
215
216 pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
218 where
219 Q: Hash + Eq + ?Sized,
220 K: Borrow<Q>,
221 {
222 self.inner.remove(key)
223 }
224}
225
226impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S> {
227 type Item = (&'a K, &'a V);
228
229 type IntoIter = inner::Iter<'a, K, V>;
230
231 fn into_iter(self) -> Self::IntoIter {
232 self.iter()
233 }
234}
235
236impl<'a, K, V, S> IntoIterator for &'a mut HashMap<K, V, S> {
237 type Item = (&'a K, &'a mut V);
238
239 type IntoIter = inner::IterMut<'a, K, V>;
240
241 fn into_iter(self) -> Self::IntoIter {
242 self.iter_mut()
243 }
244}
245
246impl<K, V, S> IntoIterator for HashMap<K, V, S> {
247 type Item = (K, V);
248
249 type IntoIter = inner::IntoIter<K, V>;
250
251 fn into_iter(self) -> Self::IntoIter {
252 self.inner.into_iter()
253 }
254}