1use crate::common::*;
4use crate::compat::*;
5use crate::inner;
6
7use super::traits::*;
8use super::weak_key_hash_map as base;
9
10pub use super::WeakHashSet;
11
12universal_hashless_members! {
13 WeakHashSet ("`WeakHashSet`", a "set")
14 base::WeakKeyHashMap::with_capacity_and_hasher
15 {T}
16}
17
18impl<T: WeakKey, S: BuildHasher> WeakHashSet<T, S> {
19 universal_key_independent_members! {"elements"}
20
21 pub fn contains<Q>(&self, key: &Q) -> bool
27 where
28 Q: ?Sized + Eq + Hash,
29 T::Key: Borrow<Q>,
30 {
31 self.0.contains_key(key)
32 }
33
34 pub fn get<Q>(&self, key: &Q) -> Option<T::Strong>
55 where
56 Q: ?Sized + Eq + Hash,
57 T::Key: Borrow<Q>,
58 {
59 self.0.get_key(key)
60 }
61
62 pub fn insert(&mut self, key: T::Strong) -> bool {
72 self.0.insert(key, ()).is_some()
73 }
74
75 pub fn remove<Q>(&mut self, key: &Q) -> bool
81 where
82 Q: ?Sized + Eq + Hash,
83 T::Key: Borrow<Q>,
84 {
85 self.0.remove(key).is_some()
86 }
87
88 pub fn take<Q>(&mut self, key: &Q) -> Option<T::Strong>
92 where
93 Q: ?Sized + Eq + Hash,
94 T::Key: Borrow<Q>,
95 {
96 self.0.remove_entry(key).map(|(k, ())| k)
97 }
98
99 pub fn retain<F>(&mut self, mut f: F)
105 where
106 F: FnMut(T::Strong) -> bool,
107 {
108 self.0.retain(|k, _| f(k));
109 }
110
111 pub fn is_subset<S1>(&self, other: &WeakHashSet<T, S1>) -> bool
117 where
118 S1: BuildHasher,
119 {
120 self.0.domain_is_subset(&other.0)
121 }
122
123 fn contains_strong(&self, item: &T::Strong) -> bool {
125 T::with_key(item, |k| self.contains(k))
126 }
127
128 set_op_methods! {WeakHashSet}
129 set_relationships! {WeakHashSet}
130}
131
132pub struct Iter<'a, T: 'a>(base::Keys<'a, T, ()>);
134
135impl<'a, T: WeakElement> Iterator for Iter<'a, T> {
136 type Item = T::Strong;
137
138 fn next(&mut self) -> Option<Self::Item> {
139 self.0.next()
140 }
141
142 fn size_hint(&self) -> (usize, Option<usize>) {
143 self.0.size_hint()
144 }
145}
146
147pub struct IntoIter<T>(base::IntoIter<T, ()>);
149
150impl<T: WeakElement> Iterator for IntoIter<T> {
151 type Item = T::Strong;
152
153 fn next(&mut self) -> Option<Self::Item> {
154 self.0.next().map(|pair| pair.0)
155 }
156
157 fn size_hint(&self) -> (usize, Option<usize>) {
158 self.0.size_hint()
159 }
160}
161
162pub struct Drain<'a, T: 'a>(base::Drain<'a, T, ()>);
167
168impl<'a, T: WeakElement> Iterator for Drain<'a, T> {
169 type Item = T::Strong;
170
171 fn next(&mut self) -> Option<Self::Item> {
172 self.0.next().map(|pair| pair.0)
173 }
174
175 fn size_hint(&self) -> (usize, Option<usize>) {
176 self.0.size_hint()
177 }
178}
179
180impl<T: WeakElement, S> WeakHashSet<T, S> {
181 pub fn iter(&self) -> Iter<'_, T> {
185 Iter(self.0.keys())
186 }
187
188 pub fn drain(&mut self) -> Drain<'_, T> {
192 Drain(self.0.drain())
193 }
194
195 pub fn extract_if<'a, F>(&'a mut self, mut f: F) -> ExtractIf<'a, T, F>
205 where
206 F: FnMut(T::Strong) -> bool + 'a,
207 {
208 ExtractIf {
209 inner: self.0 .0.extract_if(move |e| {
210 if let Some(k) = e.0.val.view() {
211 f(k)
212 } else {
213 true
214 }
215 }),
216 _phantom: PhantomData,
217 }
218 }
219}
220
221pub struct ExtractIf<'a, T: WeakElement, F> {
223 inner: inner::ExtractIf<'a, inner::WeakK<T>, inner::Owned<()>>,
225 _phantom: PhantomData<F>,
227}
228
229impl<'a, T: WeakElement, F> Iterator for ExtractIf<'a, T, F> {
230 type Item = T::Strong;
231
232 fn next(&mut self) -> Option<Self::Item> {
233 self.inner.next().map(|(k, ())| k)
234 }
235
236 fn size_hint(&self) -> (usize, Option<usize>) {
237 self.inner.size_hint()
238 }
239}
240
241set_op_types! {WeakHashSet where {T: WeakKey}}
242set_operators! {WeakHashSet where {T: WeakKey}}
243
244impl<T, S, S1> PartialEq<WeakHashSet<T, S1>> for WeakHashSet<T, S>
245where
246 T: WeakKey,
247 S: BuildHasher,
248 S1: BuildHasher,
249{
250 fn eq(&self, other: &WeakHashSet<T, S1>) -> bool {
251 self.0 == other.0
252 }
253}
254
255impl<T: WeakKey, S: BuildHasher> Eq for WeakHashSet<T, S> where T::Key: Eq {}
256
257impl<T, S> FromIterator<T::Strong> for WeakHashSet<T, S>
258where
259 T: WeakKey,
260 S: BuildHasher + Default,
261{
262 fn from_iter<I: IntoIterator<Item = T::Strong>>(iter: I) -> Self {
263 WeakHashSet(base::WeakKeyHashMap::<T, (), S>::from_iter(
264 iter.into_iter().map(|k| (k, ())),
265 ))
266 }
267}
268
269impl<T: WeakKey, const N: usize> From<[T::Strong; N]> for WeakHashSet<T, RandomState> {
270 fn from(value: [T::Strong; N]) -> Self {
275 Self::from_iter(value)
276 }
277}
278
279impl<T: WeakKey, S: BuildHasher> Extend<T::Strong> for WeakHashSet<T, S> {
280 fn extend<I: IntoIterator<Item = T::Strong>>(&mut self, iter: I) {
281 self.0.extend(iter.into_iter().map(|k| (k, ())));
282 }
283}
284
285impl<T: WeakElement, S> Debug for WeakHashSet<T, S>
286where
287 T::Strong: Debug,
288{
289 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
290 f.debug_set().entries(self.iter()).finish()
291 }
292}
293
294impl<T: WeakElement, S> IntoIterator for WeakHashSet<T, S> {
295 type Item = T::Strong;
296 type IntoIter = IntoIter<T>;
297
298 fn into_iter(self) -> Self::IntoIter {
302 IntoIter(self.0.into_iter())
303 }
304}
305
306impl<'a, T: WeakElement, S> IntoIterator for &'a WeakHashSet<T, S> {
307 type Item = T::Strong;
308 type IntoIter = Iter<'a, T>;
309
310 fn into_iter(self) -> Self::IntoIter {
314 Iter(self.0.keys())
315 }
316}
317
318fn sort_by_size<'a, T: WeakKey, S: BuildHasher>(
321 a: &'a WeakHashSet<T, S>,
322 b: &'a WeakHashSet<T, S>,
323) -> (&'a WeakHashSet<T, S>, &'a WeakHashSet<T, S>) {
324 if a.len() < b.len() {
325 (a, b)
326 } else {
327 (b, a)
328 }
329}
330
331#[cfg(test)]
332mod test {
333 use super::*;
334 use crate::{
335 compat::rc::{Rc, Weak},
336 tests::util::VecDebugAsSet,
337 };
338
339 crate::tests::common::empty_constructor_tests! {WeakHashSet<Weak<u8>>}
340 crate::tests::set_operations::set_operation_tests! {WeakHashSet, 0}
341
342 #[test]
344 fn test_retain_regresion() {
345 for _ in 0..20 {
347 let mut set: WeakHashSet<Weak<u8>> = WeakHashSet::default();
348 let mut preserve_vals = Vec::new();
349
350 const N: u8 = 50;
351
352 for i in 0..N {
353 let rc = Rc::new(i);
354 preserve_vals.push(rc.clone());
355 set.insert(rc);
356 }
357
358 let rc_n = Rc::new(N);
359 set.insert(rc_n.clone());
360
361 drop(preserve_vals);
362
363 let mut retain_called_on = Vec::new();
364 set.retain(|val| {
365 retain_called_on.push(val);
366 false
367 });
368
369 assert_eq!(retain_called_on, vec![rc_n]);
370 }
371 }
372
373 #[test]
374 fn test_take() {
375 let s = [Rc::new(1), Rc::new(2), Rc::new(3)];
376 let mut set: WeakHashSet<Weak<u32>> = s.clone().into();
377 assert_eq!(set.iter().count(), 3);
378
379 let v = set.take(&2);
380 assert_eq!(v, Some(Rc::new(2)));
381 assert_eq!(set.iter().count(), 2);
382 assert!(Rc::ptr_eq(&v.expect("absent suddenly!"), &s[1]));
383
384 let v = set.take(&2);
385 assert!(v.is_none());
386 }
387
388 #[test]
389 fn test_debug() {
390 let s = [Rc::new(1), Rc::new(2)];
391 let set: WeakHashSet<Weak<u32>> = s.clone().into();
392 let v: VecDebugAsSet<_> = set.iter().collect();
393 assert_eq!(format!("{v:?}"), format!("{set:?}"));
394 }
395}