Skip to main content

wasmtime_environ/collections/
hash_set.rs

1use crate::error::OutOfMemory;
2use core::{
3    borrow::Borrow,
4    fmt,
5    hash::{BuildHasher, Hash},
6};
7
8#[cfg(feature = "std")]
9use std::{collections::hash_set as inner, hash::RandomState as DefaultHashBuilder};
10
11#[cfg(not(feature = "std"))]
12use hashbrown::{DefaultHashBuilder, hash_set as inner};
13
14/// A wrapper type around [`hashbrown::hash_set::HashSet`] that only exposes
15/// fallible allocation.
16pub struct HashSet<T, S = DefaultHashBuilder> {
17    inner: inner::HashSet<T, S>,
18}
19
20impl<T, S> Default for HashSet<T, S>
21where
22    S: Default,
23{
24    fn default() -> Self {
25        Self {
26            inner: inner::HashSet::default(),
27        }
28    }
29}
30
31impl<T, S> PartialEq for HashSet<T, S>
32where
33    T: Eq + Hash,
34    S: BuildHasher,
35{
36    fn eq(&self, other: &Self) -> bool {
37        self.inner.eq(&other.inner)
38    }
39}
40
41impl<T, S> Eq for HashSet<T, S>
42where
43    T: Eq + Hash,
44    S: BuildHasher,
45{
46}
47
48impl<T, S> fmt::Debug for HashSet<T, S>
49where
50    T: fmt::Debug,
51{
52    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53        fmt::Debug::fmt(&self.inner, f)
54    }
55}
56
57impl<T> HashSet<T, DefaultHashBuilder> {
58    /// Same as [`hashbrown::hash_set::HashSet::new`].
59    pub fn new() -> Self {
60        Self {
61            inner: inner::HashSet::new(),
62        }
63    }
64}
65
66impl<T> HashSet<T, DefaultHashBuilder>
67where
68    T: Eq + Hash,
69{
70    /// Same as [`hashbrown::hash_set::HashSet::with_capacity`] but returns an
71    /// error on allocation failure.
72    pub fn with_capacity(capacity: usize) -> Result<Self, OutOfMemory> {
73        let mut set = Self::new();
74        set.reserve(capacity)?;
75        Ok(set)
76    }
77}
78
79impl<T, S> HashSet<T, S> {
80    /// Same as [`hashbrown::hash_set::HashSet::with_hasher`].
81    pub const fn with_hasher(hasher: S) -> Self {
82        Self {
83            inner: inner::HashSet::with_hasher(hasher),
84        }
85    }
86
87    /// Same as [`hashbrown::hash_set::HashSet::capacity`].
88    pub fn capacity(&self) -> usize {
89        self.inner.capacity()
90    }
91
92    /// Same as [`hashbrown::hash_set::HashSet::iter`].
93    pub fn iter(&self) -> inner::Iter<'_, T> {
94        self.inner.iter()
95    }
96
97    /// Same as [`hashbrown::hash_set::HashSet::len`].
98    pub fn len(&self) -> usize {
99        self.inner.len()
100    }
101
102    /// Same as [`hashbrown::hash_set::HashSet::is_empty`].
103    pub fn is_empty(&self) -> bool {
104        self.inner.is_empty()
105    }
106
107    /// Same as [`hashbrown::hash_set::HashSet::drain`].
108    pub fn drain(&mut self) -> inner::Drain<'_, T> {
109        self.inner.drain()
110    }
111
112    /// Same as [`hashbrown::hash_set::HashSet::retain`].
113    pub fn retain<F>(&mut self, f: F)
114    where
115        F: FnMut(&T) -> bool,
116    {
117        self.inner.retain(f);
118    }
119
120    /// Same as [`hashbrown::hash_set::HashSet::extract_if`].
121    pub fn extract_if<F>(&mut self, f: F) -> inner::ExtractIf<'_, T, F>
122    where
123        F: FnMut(&T) -> bool,
124    {
125        self.inner.extract_if(f)
126    }
127
128    /// Same as [`hashbrown::hash_set::HashSet::clear`].
129    pub fn clear(&mut self) {
130        self.inner.clear();
131    }
132}
133
134impl<T, S> HashSet<T, S>
135where
136    T: Eq + Hash,
137    S: BuildHasher,
138{
139    /// Same as [`hashbrown::hash_set::HashSet::with_capacity_and_hasher`] but
140    /// returns an error on allocation failure.
141    pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Result<Self, OutOfMemory> {
142        let mut map = Self::with_hasher(hasher);
143        map.reserve(capacity)?;
144        Ok(map)
145    }
146
147    /// Same as [`hashbrown::hash_set::HashSet::reserve`] but returns an error
148    /// on allocation failure.
149    pub fn reserve(&mut self, additional: usize) -> Result<(), OutOfMemory> {
150        self.inner.try_reserve(additional).map_err(|_| {
151            OutOfMemory::new(
152                self.len()
153                    .saturating_add(additional)
154                    .saturating_mul(core::mem::size_of::<T>()),
155            )
156        })
157    }
158
159    /// Same as [`hashbrown::hash_set::HashSet::contains`].
160    pub fn contains<Q>(&self, value: &Q) -> bool
161    where
162        Q: Hash + Eq + ?Sized,
163        T: Borrow<Q>,
164    {
165        self.inner.contains(value)
166    }
167
168    /// Same as [`hashbrown::hash_set::HashSet::get`].
169    pub fn get<Q>(&self, value: &Q) -> Option<&T>
170    where
171        Q: Hash + Eq + ?Sized,
172        T: Borrow<Q>,
173    {
174        self.inner.get(value)
175    }
176
177    /// Same as [`hashbrown::hash_set::HashSet::insert`] but returns an error on
178    /// allocation failure.
179    pub fn insert(&mut self, value: T) -> Result<bool, OutOfMemory> {
180        self.reserve(1)?;
181        Ok(self.inner.insert(value))
182    }
183
184    /// Same as [`hashbrown::hash_set::HashSet::remove`].
185    pub fn remove<Q>(&mut self, value: &Q) -> bool
186    where
187        Q: Hash + Eq + ?Sized,
188        T: Borrow<Q>,
189    {
190        self.inner.remove(value)
191    }
192
193    /// Same as [`hashbrown::hash_set::HashSet::take`].
194    pub fn take<Q>(&mut self, value: &Q) -> Option<T>
195    where
196        Q: Hash + Eq + ?Sized,
197        T: Borrow<Q>,
198    {
199        self.inner.take(value)
200    }
201}