weak_table/
weak_hash_set.rs1use crate::compat::*;
4
5use super::traits::*;
6use super::weak_key_hash_map as base;
7
8pub use super::WeakHashSet;
9
10impl<T: WeakKey> WeakHashSet<T, RandomState> {
11 pub fn new() -> Self {
15 WeakHashSet(base::WeakKeyHashMap::new())
16 }
17
18 pub fn with_capacity(capacity: usize) -> Self {
22 WeakHashSet(base::WeakKeyHashMap::with_capacity(capacity))
23 }
24}
25
26impl<T: WeakKey, S: BuildHasher> WeakHashSet<T, S> {
27 pub fn with_hasher(hash_builder: S) -> Self {
31 WeakHashSet(base::WeakKeyHashMap::with_hasher(hash_builder))
32 }
33
34 pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
38 WeakHashSet(base::WeakKeyHashMap::with_capacity_and_hasher(
39 capacity,
40 hash_builder,
41 ))
42 }
43
44 pub fn hasher(&self) -> &S {
48 self.0.hasher()
49 }
50
51 pub fn capacity(&self) -> usize {
55 self.0.capacity()
56 }
57
58 pub fn remove_expired(&mut self) {
62 self.0.remove_expired();
63 }
64
65 pub fn reserve(&mut self, additional_capacity: usize) {
72 self.0.reserve(additional_capacity);
73 }
74
75 pub fn shrink_to_fit(&mut self) {
79 self.0.shrink_to_fit();
80 }
81
82 pub fn len(&self) -> usize {
89 self.0.len()
90 }
91
92 pub fn is_empty(&self) -> bool {
99 self.0.is_empty()
100 }
101
102 pub fn load_factor(&self) -> f32 {
108 self.0.load_factor()
109 }
110
111 pub fn clear(&mut self) {
115 self.0.clear();
116 }
117
118 pub fn contains<Q>(&self, key: &Q) -> bool
124 where
125 Q: ?Sized + Eq + Hash,
126 T::Key: Borrow<Q>,
127 {
128 self.0.contains_key(key)
129 }
130
131 pub fn get<Q>(&self, key: &Q) -> Option<T::Strong>
152 where
153 Q: ?Sized + Eq + Hash,
154 T::Key: Borrow<Q>,
155 {
156 self.0.get_key(key)
157 }
158
159 pub fn insert(&mut self, key: T::Strong) -> bool {
164 self.0.insert(key, ()).is_some()
165 }
166
167 pub fn remove<Q>(&mut self, key: &Q) -> bool
173 where
174 Q: ?Sized + Eq + Hash,
175 T::Key: Borrow<Q>,
176 {
177 self.0.remove(key).is_some()
178 }
179
180 pub fn retain<F>(&mut self, mut f: F)
186 where
187 F: FnMut(T::Strong) -> bool,
188 {
189 self.0.retain(|k, _| f(k));
190 }
191
192 pub fn is_subset<S1>(&self, other: &WeakHashSet<T, S1>) -> bool
198 where
199 S1: BuildHasher,
200 {
201 self.0.domain_is_subset(&other.0)
202 }
203}
204
205pub struct Iter<'a, T: 'a>(base::Keys<'a, T, ()>);
207
208impl<'a, T: WeakElement> Iterator for Iter<'a, T> {
209 type Item = T::Strong;
210
211 fn next(&mut self) -> Option<Self::Item> {
212 self.0.next()
213 }
214
215 fn size_hint(&self) -> (usize, Option<usize>) {
216 self.0.size_hint()
217 }
218}
219
220pub struct IntoIter<T>(base::IntoIter<T, ()>);
222
223impl<T: WeakElement> Iterator for IntoIter<T> {
224 type Item = T::Strong;
225
226 fn next(&mut self) -> Option<Self::Item> {
227 self.0.next().map(|pair| pair.0)
228 }
229
230 fn size_hint(&self) -> (usize, Option<usize>) {
231 self.0.size_hint()
232 }
233}
234
235pub struct Drain<'a, T: 'a>(base::Drain<'a, T, ()>);
240
241impl<'a, T: WeakElement> Iterator for Drain<'a, T> {
242 type Item = T::Strong;
243
244 fn next(&mut self) -> Option<Self::Item> {
245 self.0.next().map(|pair| pair.0)
246 }
247
248 fn size_hint(&self) -> (usize, Option<usize>) {
249 self.0.size_hint()
250 }
251}
252
253impl<T: WeakKey, S> WeakHashSet<T, S> {
254 pub fn iter(&self) -> Iter<'_, T> {
258 Iter(self.0.keys())
259 }
260
261 pub fn drain(&mut self) -> Drain<'_, T> {
265 Drain(self.0.drain())
266 }
267}
268
269impl<T, S, S1> PartialEq<WeakHashSet<T, S1>> for WeakHashSet<T, S>
270where
271 T: WeakKey,
272 S: BuildHasher,
273 S1: BuildHasher,
274{
275 fn eq(&self, other: &WeakHashSet<T, S1>) -> bool {
276 self.0 == other.0
277 }
278}
279
280impl<T: WeakKey, S: BuildHasher> Eq for WeakHashSet<T, S> where T::Key: Eq {}
281
282impl<T: WeakKey, S: BuildHasher + Default> Default for WeakHashSet<T, S> {
283 fn default() -> Self {
284 WeakHashSet(base::WeakKeyHashMap::<T, (), S>::default())
285 }
286}
287
288impl<T, S> FromIterator<T::Strong> for WeakHashSet<T, S>
289where
290 T: WeakKey,
291 S: BuildHasher + Default,
292{
293 fn from_iter<I: IntoIterator<Item = T::Strong>>(iter: I) -> Self {
294 WeakHashSet(base::WeakKeyHashMap::<T, (), S>::from_iter(
295 iter.into_iter().map(|k| (k, ())),
296 ))
297 }
298}
299
300impl<T: WeakKey, S: BuildHasher> Extend<T::Strong> for WeakHashSet<T, S> {
301 fn extend<I: IntoIterator<Item = T::Strong>>(&mut self, iter: I) {
302 self.0.extend(iter.into_iter().map(|k| (k, ())));
303 }
304}
305
306impl<T: WeakKey, S> Debug for WeakHashSet<T, S>
307where
308 T::Strong: Debug,
309{
310 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
311 self.0.fmt(f)
312 }
313}
314
315impl<T: WeakKey, S> IntoIterator for WeakHashSet<T, S> {
316 type Item = T::Strong;
317 type IntoIter = IntoIter<T>;
318
319 fn into_iter(self) -> Self::IntoIter {
323 IntoIter(self.0.into_iter())
324 }
325}
326
327impl<'a, T: WeakKey, S> IntoIterator for &'a WeakHashSet<T, S> {
328 type Item = T::Strong;
329 type IntoIter = Iter<'a, T>;
330
331 fn into_iter(self) -> Self::IntoIter {
335 Iter(self.0.keys())
336 }
337}
338
339#[cfg(test)]
340mod test {
341 use super::*;
342 use crate::compat::rc::{Rc, Weak};
343
344 #[test]
346 fn test_retain_regresion() {
347 for _ in 0..20 {
349 let mut set: WeakHashSet<Weak<u8>> = WeakHashSet::default();
350 let mut preserve_vals = Vec::new();
351
352 const N: u8 = 50;
353
354 for i in 0..N {
355 let rc = Rc::new(i);
356 preserve_vals.push(rc.clone());
357 set.insert(rc);
358 }
359
360 let rc_n = Rc::new(N);
361 set.insert(rc_n.clone());
362
363 drop(preserve_vals);
364
365 let mut retain_called_on = Vec::new();
366 set.retain(|val| {
367 retain_called_on.push(val);
368 false
369 });
370
371 assert_eq!(retain_called_on, vec![rc_n]);
372 }
373 }
374}