Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/environ/src/collections/hash_map.rs
3069 views
1
use crate::error::OutOfMemory;
2
use core::{
3
borrow::Borrow,
4
fmt,
5
hash::{BuildHasher, Hash},
6
mem,
7
};
8
9
#[cfg(feature = "std")]
10
use std::{collections::hash_map as inner, hash::RandomState as DefaultHashBuilder};
11
12
#[cfg(not(feature = "std"))]
13
use hashbrown::{DefaultHashBuilder, hash_map as inner};
14
use wasmtime_core::alloc::TryClone;
15
16
/// A wrapper type around [`hashbrown::hash_map::HashMap`] that only exposes
17
/// fallible allocation.
18
pub struct HashMap<K, V, S = DefaultHashBuilder> {
19
inner: inner::HashMap<K, V, S>,
20
}
21
22
impl<K, V, S> TryClone for HashMap<K, V, S>
23
where
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
38
impl<K, V, S> Default for HashMap<K, V, S>
39
where
40
S: Default,
41
{
42
fn default() -> Self {
43
Self {
44
inner: inner::HashMap::default(),
45
}
46
}
47
}
48
49
impl<K, V, S> PartialEq for HashMap<K, V, S>
50
where
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
60
impl<K, V, S> Eq for HashMap<K, V, S>
61
where
62
K: Eq + Hash,
63
V: Eq,
64
S: BuildHasher,
65
{
66
}
67
68
impl<K, V, S> fmt::Debug for HashMap<K, V, S>
69
where
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
78
impl<K, V> HashMap<K, V, DefaultHashBuilder> {
79
/// Same as [`hashbrown::hash_map::HashMap::new`].
80
pub fn new() -> Self {
81
Self {
82
inner: inner::HashMap::new(),
83
}
84
}
85
}
86
87
impl<K, V> HashMap<K, V, DefaultHashBuilder>
88
where
89
K: Eq + Hash,
90
{
91
/// Same as [`hashbrown::hash_map::HashMap::with_capacity`] but returns an
92
/// error on allocation failure.
93
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
100
impl<K, V, S> HashMap<K, V, S> {
101
/// Same as [`hashbrown::hash_map::HashMap::with_hasher`].
102
pub const fn with_hasher(hasher: S) -> Self {
103
Self {
104
inner: inner::HashMap::with_hasher(hasher),
105
}
106
}
107
108
/// Same as [`hashbrown::hash_map::HashMap::hasher`].
109
pub fn hasher(&self) -> &S {
110
self.inner.hasher()
111
}
112
113
/// Same as [`hashbrown::hash_map::HashMap::capacity`].
114
pub fn capacity(&self) -> usize {
115
self.inner.capacity()
116
}
117
118
/// Same as [`hashbrown::hash_map::HashMap::len`].
119
pub fn len(&self) -> usize {
120
self.inner.len()
121
}
122
123
/// Same as [`hashbrown::hash_map::HashMap::is_empty`].
124
pub fn is_empty(&self) -> bool {
125
self.inner.is_empty()
126
}
127
128
/// Same as [`hashbrown::hash_map::HashMap::drain`].
129
pub fn drain(&mut self) -> inner::Drain<'_, K, V> {
130
self.inner.drain()
131
}
132
133
/// Same as [`hashbrown::hash_map::HashMap::retain`].
134
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
/// Same as [`hashbrown::hash_map::HashMap::extract_if`].
142
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
/// Same as [`hashbrown::hash_map::HashMap::clear`].
150
pub fn clear(&mut self) {
151
self.inner.clear();
152
}
153
154
/// Same as [`hashbrown::hash_map::HashMap::iter`].
155
pub fn iter(&self) -> inner::Iter<'_, K, V> {
156
self.inner.iter()
157
}
158
159
/// Same as [`hashbrown::hash_map::HashMap::iter_mut`].
160
pub fn iter_mut(&mut self) -> inner::IterMut<'_, K, V> {
161
self.inner.iter_mut()
162
}
163
}
164
165
impl<K, V, S> HashMap<K, V, S>
166
where
167
K: Eq + Hash,
168
S: BuildHasher,
169
{
170
/// Same as [`hashbrown::hash_map::HashMap::with_capacity_and_hasher`] but
171
/// returns an error on allocation failure.
172
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
/// Same as [`hashbrown::hash_map::HashMap::reserve`] but returns an error
179
/// on allocation failure.
180
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
/// Same as [`hashbrown::hash_map::HashMap::contains_key`].
192
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
/// Same as [`hashbrown::hash_map::HashMap::get`].
201
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
/// Same as [`hashbrown::hash_map::HashMap::insert`] but returns an error on
210
/// allocation failure.
211
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
/// Same as [`hashbrown::hash_map::HashMap::remove`].
217
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
226
impl<'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
236
impl<'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
246
impl<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
}
255
256