hashbrown/set.rs
1use crate::{Equivalent, TryReserveError};
2use core::cell::UnsafeCell;
3use core::fmt;
4use core::hash::{BuildHasher, Hash};
5use core::iter::{Chain, FusedIterator};
6use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign};
7
8use super::map::{self, HashMap, Keys};
9use crate::DefaultHashBuilder;
10use crate::alloc::{Allocator, Global};
11use crate::raw::RawExtractIf;
12
13// Future Optimization (FIXME!)
14// =============================
15//
16// Iteration over zero sized values is a noop. There is no need
17// for `bucket.val` in the case of HashSet. I suppose we would need HKT
18// to get rid of it properly.
19
20/// A hash set implemented as a `HashMap` where the value is `()`.
21///
22/// As with the [`HashMap`] type, a `HashSet` requires that the elements
23/// implement the [`Eq`] and [`Hash`] traits. This can frequently be achieved by
24/// using `#[derive(PartialEq, Eq, Hash)]`. If you implement these yourself,
25/// it is important that the following property holds:
26///
27/// ```text
28/// k1 == k2 -> hash(k1) == hash(k2)
29/// ```
30///
31/// In other words, if two keys are equal, their hashes must be equal.
32///
33///
34/// It is a logic error for an item to be modified in such a way that the
35/// item's hash, as determined by the [`Hash`] trait, or its equality, as
36/// determined by the [`Eq`] trait, changes while it is in the set. This is
37/// normally only possible through [`Cell`], [`RefCell`], global state, I/O, or
38/// unsafe code.
39///
40/// It is also a logic error for the [`Hash`] implementation of a key to panic.
41/// This is generally only possible if the trait is implemented manually. If a
42/// panic does occur then the contents of the `HashSet` may become corrupted and
43/// some items may be dropped from the table.
44///
45/// # Examples
46///
47/// ```
48/// use hashbrown::HashSet;
49/// // Type inference lets us omit an explicit type signature (which
50/// // would be `HashSet<String>` in this example).
51/// let mut books = HashSet::new();
52///
53/// // Add some books.
54/// books.insert("A Dance With Dragons".to_string());
55/// books.insert("To Kill a Mockingbird".to_string());
56/// books.insert("The Odyssey".to_string());
57/// books.insert("The Great Gatsby".to_string());
58///
59/// // Check for a specific one.
60/// if !books.contains("The Winds of Winter") {
61/// println!("We have {} books, but The Winds of Winter ain't one.",
62/// books.len());
63/// }
64///
65/// // Remove a book.
66/// books.remove("The Odyssey");
67///
68/// // Iterate over everything.
69/// for book in &books {
70/// println!("{}", book);
71/// }
72/// ```
73///
74/// The easiest way to use `HashSet` with a custom type is to derive
75/// [`Eq`] and [`Hash`]. We must also derive [`PartialEq`]. This will in the
76/// future be implied by [`Eq`].
77///
78/// ```
79/// use hashbrown::HashSet;
80/// #[derive(Hash, Eq, PartialEq, Debug)]
81/// struct Viking {
82/// name: String,
83/// power: usize,
84/// }
85///
86/// let mut vikings = HashSet::new();
87///
88/// vikings.insert(Viking { name: "Einar".to_string(), power: 9 });
89/// vikings.insert(Viking { name: "Einar".to_string(), power: 9 });
90/// vikings.insert(Viking { name: "Olaf".to_string(), power: 4 });
91/// vikings.insert(Viking { name: "Harald".to_string(), power: 8 });
92///
93/// // Use derived implementation to print the vikings.
94/// for x in &vikings {
95/// println!("{:?}", x);
96/// }
97/// ```
98///
99/// A `HashSet` with fixed list of elements can be initialized from an array:
100///
101/// ```
102/// use hashbrown::HashSet;
103///
104/// let viking_names: HashSet<&'static str> =
105/// [ "Einar", "Olaf", "Harald" ].into_iter().collect();
106/// // use the values stored in the set
107/// ```
108///
109/// [`Cell`]: std::cell::Cell
110/// [`RefCell`]: std::cell::RefCell
111pub struct HashSet<T, S = DefaultHashBuilder, A: Allocator = Global> {
112 pub(crate) map: HashMap<T, (), S, A>,
113}
114
115impl<T: Clone, S: Clone, A: Allocator + Clone> Clone for HashSet<T, S, A> {
116 fn clone(&self) -> Self {
117 HashSet {
118 map: self.map.clone(),
119 }
120 }
121
122 fn clone_from(&mut self, source: &Self) {
123 self.map.clone_from(&source.map);
124 }
125}
126
127#[cfg(feature = "default-hasher")]
128impl<T> HashSet<T, DefaultHashBuilder> {
129 /// Creates an empty `HashSet`.
130 ///
131 /// The hash set is initially created with a capacity of 0, so it will not allocate until it
132 /// is first inserted into.
133 ///
134 /// # HashDoS resistance
135 ///
136 /// The `hash_builder` normally use a fixed key by default and that does
137 /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
138 /// Users who require HashDoS resistance should explicitly use
139 /// [`std::hash::RandomState`]
140 /// as the hasher when creating a [`HashSet`], for example with
141 /// [`with_hasher`](HashSet::with_hasher) method.
142 ///
143 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
144 ///
145 /// # Examples
146 ///
147 /// ```
148 /// use hashbrown::HashSet;
149 /// let set: HashSet<i32> = HashSet::new();
150 /// ```
151 #[must_use]
152 #[cfg_attr(feature = "inline-more", inline)]
153 pub fn new() -> Self {
154 Self {
155 map: HashMap::new(),
156 }
157 }
158
159 /// Creates an empty `HashSet` with the specified capacity.
160 ///
161 /// The hash set will be able to hold at least `capacity` elements without
162 /// reallocating. If `capacity` is 0, the hash set will not allocate.
163 ///
164 /// # HashDoS resistance
165 ///
166 /// The `hash_builder` normally use a fixed key by default and that does
167 /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
168 /// Users who require HashDoS resistance should explicitly use
169 /// [`std::hash::RandomState`]
170 /// as the hasher when creating a [`HashSet`], for example with
171 /// [`with_capacity_and_hasher`](HashSet::with_capacity_and_hasher) method.
172 ///
173 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
174 ///
175 /// # Examples
176 ///
177 /// ```
178 /// use hashbrown::HashSet;
179 /// let set: HashSet<i32> = HashSet::with_capacity(10);
180 /// assert!(set.capacity() >= 10);
181 /// ```
182 #[must_use]
183 #[cfg_attr(feature = "inline-more", inline)]
184 pub fn with_capacity(capacity: usize) -> Self {
185 Self {
186 map: HashMap::with_capacity(capacity),
187 }
188 }
189}
190
191#[cfg(feature = "default-hasher")]
192impl<T: Hash + Eq, A: Allocator> HashSet<T, DefaultHashBuilder, A> {
193 /// Creates an empty `HashSet`.
194 ///
195 /// The hash set is initially created with a capacity of 0, so it will not allocate until it
196 /// is first inserted into.
197 ///
198 /// # HashDoS resistance
199 ///
200 /// The `hash_builder` normally use a fixed key by default and that does
201 /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
202 /// Users who require HashDoS resistance should explicitly use
203 /// [`std::hash::RandomState`]
204 /// as the hasher when creating a [`HashSet`], for example with
205 /// [`with_hasher_in`](HashSet::with_hasher_in) method.
206 ///
207 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
208 ///
209 /// # Examples
210 ///
211 /// ```
212 /// use hashbrown::HashSet;
213 /// let set: HashSet<i32> = HashSet::new();
214 /// ```
215 #[must_use]
216 #[cfg_attr(feature = "inline-more", inline)]
217 pub fn new_in(alloc: A) -> Self {
218 Self {
219 map: HashMap::new_in(alloc),
220 }
221 }
222
223 /// Creates an empty `HashSet` with the specified capacity.
224 ///
225 /// The hash set will be able to hold at least `capacity` elements without
226 /// reallocating. If `capacity` is 0, the hash set will not allocate.
227 ///
228 /// # HashDoS resistance
229 ///
230 /// The `hash_builder` normally use a fixed key by default and that does
231 /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
232 /// Users who require HashDoS resistance should explicitly use
233 /// [`std::hash::RandomState`]
234 /// as the hasher when creating a [`HashSet`], for example with
235 /// [`with_capacity_and_hasher_in`](HashSet::with_capacity_and_hasher_in) method.
236 ///
237 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
238 ///
239 /// # Examples
240 ///
241 /// ```
242 /// use hashbrown::HashSet;
243 /// let set: HashSet<i32> = HashSet::with_capacity(10);
244 /// assert!(set.capacity() >= 10);
245 /// ```
246 #[must_use]
247 #[cfg_attr(feature = "inline-more", inline)]
248 pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
249 Self {
250 map: HashMap::with_capacity_in(capacity, alloc),
251 }
252 }
253}
254
255impl<T, S, A: Allocator> HashSet<T, S, A> {
256 /// Returns the number of elements the set can hold without reallocating.
257 ///
258 /// # Examples
259 ///
260 /// ```
261 /// use hashbrown::HashSet;
262 /// let set: HashSet<i32> = HashSet::with_capacity(100);
263 /// assert!(set.capacity() >= 100);
264 /// ```
265 #[cfg_attr(feature = "inline-more", inline)]
266 pub fn capacity(&self) -> usize {
267 self.map.capacity()
268 }
269
270 /// An iterator visiting all elements in arbitrary order.
271 /// The iterator element type is `&'a T`.
272 ///
273 /// # Examples
274 ///
275 /// ```
276 /// use hashbrown::HashSet;
277 /// let mut set = HashSet::new();
278 /// set.insert("a");
279 /// set.insert("b");
280 ///
281 /// // Will print in an arbitrary order.
282 /// for x in set.iter() {
283 /// println!("{}", x);
284 /// }
285 /// ```
286 #[cfg_attr(feature = "inline-more", inline)]
287 pub fn iter(&self) -> Iter<'_, T> {
288 Iter {
289 iter: self.map.keys(),
290 }
291 }
292
293 /// Returns the number of elements in the set.
294 ///
295 /// # Examples
296 ///
297 /// ```
298 /// use hashbrown::HashSet;
299 ///
300 /// let mut v = HashSet::new();
301 /// assert_eq!(v.len(), 0);
302 /// v.insert(1);
303 /// assert_eq!(v.len(), 1);
304 /// ```
305 #[cfg_attr(feature = "inline-more", inline)]
306 pub fn len(&self) -> usize {
307 self.map.len()
308 }
309
310 /// Returns `true` if the set contains no elements.
311 ///
312 /// # Examples
313 ///
314 /// ```
315 /// use hashbrown::HashSet;
316 ///
317 /// let mut v = HashSet::new();
318 /// assert!(v.is_empty());
319 /// v.insert(1);
320 /// assert!(!v.is_empty());
321 /// ```
322 #[cfg_attr(feature = "inline-more", inline)]
323 pub fn is_empty(&self) -> bool {
324 self.map.is_empty()
325 }
326
327 /// Clears the set, returning all elements in an iterator.
328 ///
329 /// # Examples
330 ///
331 /// ```
332 /// use hashbrown::HashSet;
333 ///
334 /// let mut set: HashSet<_> = [1, 2, 3].into_iter().collect();
335 /// assert!(!set.is_empty());
336 ///
337 /// // print 1, 2, 3 in an arbitrary order
338 /// for i in set.drain() {
339 /// println!("{}", i);
340 /// }
341 ///
342 /// assert!(set.is_empty());
343 /// ```
344 #[cfg_attr(feature = "inline-more", inline)]
345 pub fn drain(&mut self) -> Drain<'_, T, A> {
346 Drain {
347 iter: self.map.drain(),
348 }
349 }
350
351 /// Retains only the elements specified by the predicate.
352 ///
353 /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
354 ///
355 /// # Examples
356 ///
357 /// ```
358 /// use hashbrown::HashSet;
359 ///
360 /// let xs = [1,2,3,4,5,6];
361 /// let mut set: HashSet<i32> = xs.into_iter().collect();
362 /// set.retain(|&k| k % 2 == 0);
363 /// assert_eq!(set.len(), 3);
364 /// ```
365 pub fn retain<F>(&mut self, mut f: F)
366 where
367 F: FnMut(&T) -> bool,
368 {
369 self.map.retain(|k, _| f(k));
370 }
371
372 /// Drains elements which are true under the given predicate,
373 /// and returns an iterator over the removed items.
374 ///
375 /// In other words, move all elements `e` such that `f(&e)` returns `true` out
376 /// into another iterator.
377 ///
378 /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
379 /// or the iteration short-circuits, then the remaining elements will be retained.
380 /// Use [`retain()`] with a negated predicate if you do not need the returned iterator.
381 ///
382 /// [`retain()`]: HashSet::retain
383 ///
384 /// # Examples
385 ///
386 /// ```
387 /// use hashbrown::HashSet;
388 ///
389 /// let mut set: HashSet<i32> = (0..8).collect();
390 /// let drained: HashSet<i32> = set.extract_if(|v| v % 2 == 0).collect();
391 ///
392 /// let mut evens = drained.into_iter().collect::<Vec<_>>();
393 /// let mut odds = set.into_iter().collect::<Vec<_>>();
394 /// evens.sort();
395 /// odds.sort();
396 ///
397 /// assert_eq!(evens, vec![0, 2, 4, 6]);
398 /// assert_eq!(odds, vec![1, 3, 5, 7]);
399 /// ```
400 #[cfg_attr(feature = "inline-more", inline)]
401 pub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, T, F, A>
402 where
403 F: FnMut(&T) -> bool,
404 {
405 ExtractIf {
406 f,
407 inner: RawExtractIf {
408 iter: unsafe { self.map.table.iter() },
409 table: &mut self.map.table,
410 },
411 }
412 }
413
414 /// Clears the set, removing all values.
415 ///
416 /// # Examples
417 ///
418 /// ```
419 /// use hashbrown::HashSet;
420 ///
421 /// let mut v = HashSet::new();
422 /// v.insert(1);
423 /// v.clear();
424 /// assert!(v.is_empty());
425 /// ```
426 #[cfg_attr(feature = "inline-more", inline)]
427 pub fn clear(&mut self) {
428 self.map.clear();
429 }
430}
431
432impl<T, S> HashSet<T, S, Global> {
433 /// Creates a new empty hash set which will use the given hasher to hash
434 /// keys.
435 ///
436 /// The hash set is initially created with a capacity of 0, so it will not
437 /// allocate until it is first inserted into.
438 ///
439 /// # HashDoS resistance
440 ///
441 /// The `hash_builder` normally use a fixed key by default and that does
442 /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
443 /// Users who require HashDoS resistance should explicitly use
444 /// [`std::hash::RandomState`]
445 /// as the hasher when creating a [`HashSet`].
446 ///
447 /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
448 /// the `HashSet` to be useful, see its documentation for details.
449 ///
450 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
451 ///
452 /// # Examples
453 ///
454 /// ```
455 /// use hashbrown::HashSet;
456 /// use hashbrown::DefaultHashBuilder;
457 ///
458 /// let s = DefaultHashBuilder::default();
459 /// let mut set = HashSet::with_hasher(s);
460 /// set.insert(2);
461 /// ```
462 #[must_use]
463 #[cfg_attr(feature = "inline-more", inline)]
464 #[cfg_attr(feature = "rustc-dep-of-std", rustc_const_stable_indirect)]
465 pub const fn with_hasher(hasher: S) -> Self {
466 Self {
467 map: HashMap::with_hasher(hasher),
468 }
469 }
470
471 /// Creates an empty `HashSet` with the specified capacity, using
472 /// `hasher` to hash the keys.
473 ///
474 /// The hash set will be able to hold at least `capacity` elements without
475 /// reallocating. If `capacity` is 0, the hash set will not allocate.
476 ///
477 /// # HashDoS resistance
478 ///
479 /// The `hash_builder` normally use a fixed key by default and that does
480 /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
481 /// Users who require HashDoS resistance should explicitly use
482 /// [`std::hash::RandomState`]
483 /// as the hasher when creating a [`HashSet`].
484 ///
485 /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
486 /// the `HashSet` to be useful, see its documentation for details.
487 ///
488 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
489 ///
490 /// # Examples
491 ///
492 /// ```
493 /// use hashbrown::HashSet;
494 /// use hashbrown::DefaultHashBuilder;
495 ///
496 /// let s = DefaultHashBuilder::default();
497 /// let mut set = HashSet::with_capacity_and_hasher(10, s);
498 /// set.insert(1);
499 /// ```
500 #[must_use]
501 #[cfg_attr(feature = "inline-more", inline)]
502 pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self {
503 Self {
504 map: HashMap::with_capacity_and_hasher(capacity, hasher),
505 }
506 }
507}
508
509impl<T, S, A> HashSet<T, S, A>
510where
511 A: Allocator,
512{
513 /// Returns a reference to the underlying allocator.
514 #[inline]
515 pub fn allocator(&self) -> &A {
516 self.map.allocator()
517 }
518
519 /// Creates a new empty hash set which will use the given hasher to hash
520 /// keys.
521 ///
522 /// The hash set is initially created with a capacity of 0, so it will not
523 /// allocate until it is first inserted into.
524 ///
525 /// # HashDoS resistance
526 ///
527 /// The `hash_builder` normally use a fixed key by default and that does
528 /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
529 /// Users who require HashDoS resistance should explicitly use
530 /// [`std::hash::RandomState`]
531 /// as the hasher when creating a [`HashSet`].
532 ///
533 /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
534 /// the `HashSet` to be useful, see its documentation for details.
535 ///
536 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
537 ///
538 /// # Examples
539 ///
540 /// ```
541 /// use hashbrown::HashSet;
542 /// use hashbrown::DefaultHashBuilder;
543 ///
544 /// let s = DefaultHashBuilder::default();
545 /// let mut set = HashSet::with_hasher(s);
546 /// set.insert(2);
547 /// ```
548 #[must_use]
549 #[cfg_attr(feature = "inline-more", inline)]
550 #[cfg_attr(feature = "rustc-dep-of-std", rustc_const_stable_indirect)]
551 pub const fn with_hasher_in(hasher: S, alloc: A) -> Self {
552 Self {
553 map: HashMap::with_hasher_in(hasher, alloc),
554 }
555 }
556
557 /// Creates an empty `HashSet` with the specified capacity, using
558 /// `hasher` to hash the keys.
559 ///
560 /// The hash set will be able to hold at least `capacity` elements without
561 /// reallocating. If `capacity` is 0, the hash set will not allocate.
562 ///
563 /// # HashDoS resistance
564 ///
565 /// The `hash_builder` normally use a fixed key by default and that does
566 /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
567 /// Users who require HashDoS resistance should explicitly use
568 /// [`std::hash::RandomState`]
569 /// as the hasher when creating a [`HashSet`].
570 ///
571 /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
572 /// the `HashSet` to be useful, see its documentation for details.
573 ///
574 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
575 ///
576 /// # Examples
577 ///
578 /// ```
579 /// use hashbrown::HashSet;
580 /// use hashbrown::DefaultHashBuilder;
581 ///
582 /// let s = DefaultHashBuilder::default();
583 /// let mut set = HashSet::with_capacity_and_hasher(10, s);
584 /// set.insert(1);
585 /// ```
586 #[must_use]
587 #[cfg_attr(feature = "inline-more", inline)]
588 pub fn with_capacity_and_hasher_in(capacity: usize, hasher: S, alloc: A) -> Self {
589 Self {
590 map: HashMap::with_capacity_and_hasher_in(capacity, hasher, alloc),
591 }
592 }
593
594 /// Returns a reference to the set's [`BuildHasher`].
595 ///
596 /// # Examples
597 ///
598 /// ```
599 /// use hashbrown::HashSet;
600 /// use hashbrown::DefaultHashBuilder;
601 ///
602 /// let hasher = DefaultHashBuilder::default();
603 /// let set: HashSet<i32> = HashSet::with_hasher(hasher);
604 /// let hasher: &DefaultHashBuilder = set.hasher();
605 /// ```
606 #[cfg_attr(feature = "inline-more", inline)]
607 pub fn hasher(&self) -> &S {
608 self.map.hasher()
609 }
610}
611
612impl<T, S, A> HashSet<T, S, A>
613where
614 T: Eq + Hash,
615 S: BuildHasher,
616 A: Allocator,
617{
618 /// Reserves capacity for at least `additional` more elements to be inserted
619 /// in the `HashSet`. The collection may reserve more space to avoid
620 /// frequent reallocations.
621 ///
622 /// # Panics
623 ///
624 /// Panics if the new capacity exceeds [`isize::MAX`] bytes and [`abort`] the program
625 /// in case of allocation error. Use [`try_reserve`](HashSet::try_reserve) instead
626 /// if you want to handle memory allocation failure.
627 ///
628 /// [`abort`]: stdalloc::alloc::handle_alloc_error
629 ///
630 /// # Examples
631 ///
632 /// ```
633 /// use hashbrown::HashSet;
634 /// let mut set: HashSet<i32> = HashSet::new();
635 /// set.reserve(10);
636 /// assert!(set.capacity() >= 10);
637 /// ```
638 #[cfg_attr(feature = "inline-more", inline)]
639 pub fn reserve(&mut self, additional: usize) {
640 self.map.reserve(additional);
641 }
642
643 /// Tries to reserve capacity for at least `additional` more elements to be inserted
644 /// in the given `HashSet<K,V>`. The collection may reserve more space to avoid
645 /// frequent reallocations.
646 ///
647 /// # Errors
648 ///
649 /// If the capacity overflows, or the allocator reports a failure, then an error
650 /// is returned.
651 ///
652 /// # Examples
653 ///
654 /// ```
655 /// use hashbrown::HashSet;
656 /// let mut set: HashSet<i32> = HashSet::new();
657 /// set.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?");
658 /// ```
659 #[cfg_attr(feature = "inline-more", inline)]
660 pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
661 self.map.try_reserve(additional)
662 }
663
664 /// Shrinks the capacity of the set as much as possible. It will drop
665 /// down as much as possible while maintaining the internal rules
666 /// and possibly leaving some space in accordance with the resize policy.
667 ///
668 /// # Examples
669 ///
670 /// ```
671 /// use hashbrown::HashSet;
672 ///
673 /// let mut set = HashSet::with_capacity(100);
674 /// set.insert(1);
675 /// set.insert(2);
676 /// assert!(set.capacity() >= 100);
677 /// set.shrink_to_fit();
678 /// assert!(set.capacity() >= 2);
679 /// ```
680 #[cfg_attr(feature = "inline-more", inline)]
681 pub fn shrink_to_fit(&mut self) {
682 self.map.shrink_to_fit();
683 }
684
685 /// Shrinks the capacity of the set with a lower limit. It will drop
686 /// down no lower than the supplied limit while maintaining the internal rules
687 /// and possibly leaving some space in accordance with the resize policy.
688 ///
689 /// Panics if the current capacity is smaller than the supplied
690 /// minimum capacity.
691 ///
692 /// # Examples
693 ///
694 /// ```
695 /// use hashbrown::HashSet;
696 ///
697 /// let mut set = HashSet::with_capacity(100);
698 /// set.insert(1);
699 /// set.insert(2);
700 /// assert!(set.capacity() >= 100);
701 /// set.shrink_to(10);
702 /// assert!(set.capacity() >= 10);
703 /// set.shrink_to(0);
704 /// assert!(set.capacity() >= 2);
705 /// ```
706 #[cfg_attr(feature = "inline-more", inline)]
707 pub fn shrink_to(&mut self, min_capacity: usize) {
708 self.map.shrink_to(min_capacity);
709 }
710
711 /// Visits the values representing the difference,
712 /// i.e., the values that are in `self` but not in `other`.
713 ///
714 /// # Examples
715 ///
716 /// ```
717 /// use hashbrown::HashSet;
718 /// let a: HashSet<_> = [1, 2, 3].into_iter().collect();
719 /// let b: HashSet<_> = [4, 2, 3, 4].into_iter().collect();
720 ///
721 /// // Can be seen as `a - b`.
722 /// for x in a.difference(&b) {
723 /// println!("{}", x); // Print 1
724 /// }
725 ///
726 /// let diff: HashSet<_> = a.difference(&b).collect();
727 /// assert_eq!(diff, [1].iter().collect());
728 ///
729 /// // Note that difference is not symmetric,
730 /// // and `b - a` means something else:
731 /// let diff: HashSet<_> = b.difference(&a).collect();
732 /// assert_eq!(diff, [4].iter().collect());
733 /// ```
734 #[cfg_attr(feature = "inline-more", inline)]
735 pub fn difference<'a>(&'a self, other: &'a Self) -> Difference<'a, T, S, A> {
736 Difference {
737 iter: self.iter(),
738 other,
739 }
740 }
741
742 /// Visits the values representing the symmetric difference,
743 /// i.e., the values that are in `self` or in `other` but not in both.
744 ///
745 /// # Examples
746 ///
747 /// ```
748 /// use hashbrown::HashSet;
749 /// let a: HashSet<_> = [1, 2, 3].into_iter().collect();
750 /// let b: HashSet<_> = [4, 2, 3, 4].into_iter().collect();
751 ///
752 /// // Print 1, 4 in arbitrary order.
753 /// for x in a.symmetric_difference(&b) {
754 /// println!("{}", x);
755 /// }
756 ///
757 /// let diff1: HashSet<_> = a.symmetric_difference(&b).collect();
758 /// let diff2: HashSet<_> = b.symmetric_difference(&a).collect();
759 ///
760 /// assert_eq!(diff1, diff2);
761 /// assert_eq!(diff1, [1, 4].iter().collect());
762 /// ```
763 #[cfg_attr(feature = "inline-more", inline)]
764 pub fn symmetric_difference<'a>(&'a self, other: &'a Self) -> SymmetricDifference<'a, T, S, A> {
765 SymmetricDifference {
766 iter: self.difference(other).chain(other.difference(self)),
767 }
768 }
769
770 /// Visits the values representing the intersection,
771 /// i.e., the values that are both in `self` and `other`.
772 ///
773 /// # Examples
774 ///
775 /// ```
776 /// use hashbrown::HashSet;
777 /// let a: HashSet<_> = [1, 2, 3].into_iter().collect();
778 /// let b: HashSet<_> = [4, 2, 3, 4].into_iter().collect();
779 ///
780 /// // Print 2, 3 in arbitrary order.
781 /// for x in a.intersection(&b) {
782 /// println!("{}", x);
783 /// }
784 ///
785 /// let intersection: HashSet<_> = a.intersection(&b).collect();
786 /// assert_eq!(intersection, [2, 3].iter().collect());
787 /// ```
788 #[cfg_attr(feature = "inline-more", inline)]
789 pub fn intersection<'a>(&'a self, other: &'a Self) -> Intersection<'a, T, S, A> {
790 let (smaller, larger) = if self.len() <= other.len() {
791 (self, other)
792 } else {
793 (other, self)
794 };
795 Intersection {
796 iter: smaller.iter(),
797 other: larger,
798 }
799 }
800
801 /// Visits the values representing the union,
802 /// i.e., all the values in `self` or `other`, without duplicates.
803 ///
804 /// # Examples
805 ///
806 /// ```
807 /// use hashbrown::HashSet;
808 /// let a: HashSet<_> = [1, 2, 3].into_iter().collect();
809 /// let b: HashSet<_> = [4, 2, 3, 4].into_iter().collect();
810 ///
811 /// // Print 1, 2, 3, 4 in arbitrary order.
812 /// for x in a.union(&b) {
813 /// println!("{}", x);
814 /// }
815 ///
816 /// let union: HashSet<_> = a.union(&b).collect();
817 /// assert_eq!(union, [1, 2, 3, 4].iter().collect());
818 /// ```
819 #[cfg_attr(feature = "inline-more", inline)]
820 pub fn union<'a>(&'a self, other: &'a Self) -> Union<'a, T, S, A> {
821 // We'll iterate one set in full, and only the remaining difference from the other.
822 // Use the smaller set for the difference in order to reduce hash lookups.
823 let (smaller, larger) = if self.len() <= other.len() {
824 (self, other)
825 } else {
826 (other, self)
827 };
828 Union {
829 iter: larger.iter().chain(smaller.difference(larger)),
830 }
831 }
832
833 /// Returns `true` if the set contains a value.
834 ///
835 /// The value may be any borrowed form of the set's value type, but
836 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
837 /// the value type.
838 ///
839 /// # Examples
840 ///
841 /// ```
842 /// use hashbrown::HashSet;
843 ///
844 /// let set: HashSet<_> = [1, 2, 3].into_iter().collect();
845 /// assert_eq!(set.contains(&1), true);
846 /// assert_eq!(set.contains(&4), false);
847 /// ```
848 ///
849 #[cfg_attr(feature = "inline-more", inline)]
850 pub fn contains<Q>(&self, value: &Q) -> bool
851 where
852 Q: Hash + Equivalent<T> + ?Sized,
853 {
854 self.map.contains_key(value)
855 }
856
857 /// Returns a reference to the value in the set, if any, that is equal to the given value.
858 ///
859 /// The value may be any borrowed form of the set's value type, but
860 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
861 /// the value type.
862 ///
863 /// # Examples
864 ///
865 /// ```
866 /// use hashbrown::HashSet;
867 ///
868 /// let set: HashSet<_> = [1, 2, 3].into_iter().collect();
869 /// assert_eq!(set.get(&2), Some(&2));
870 /// assert_eq!(set.get(&4), None);
871 /// ```
872 ///
873 #[cfg_attr(feature = "inline-more", inline)]
874 pub fn get<Q>(&self, value: &Q) -> Option<&T>
875 where
876 Q: Hash + Equivalent<T> + ?Sized,
877 {
878 // Avoid `Option::map` because it bloats LLVM IR.
879 match self.map.get_key_value(value) {
880 Some((k, _)) => Some(k),
881 None => None,
882 }
883 }
884
885 /// Inserts the given `value` into the set if it is not present, then
886 /// returns a reference to the value in the set.
887 ///
888 /// # Examples
889 ///
890 /// ```
891 /// use hashbrown::HashSet;
892 ///
893 /// let mut set: HashSet<_> = [1, 2, 3].into_iter().collect();
894 /// assert_eq!(set.len(), 3);
895 /// assert_eq!(set.get_or_insert(2), &2);
896 /// assert_eq!(set.get_or_insert(100), &100);
897 /// assert_eq!(set.len(), 4); // 100 was inserted
898 /// ```
899 #[cfg_attr(feature = "inline-more", inline)]
900 pub fn get_or_insert(&mut self, value: T) -> &T {
901 match self.map.entry(value) {
902 map::Entry::Occupied(entry) => entry,
903 map::Entry::Vacant(entry) => entry.insert_entry(()),
904 }
905 .into_entry()
906 .0
907 }
908
909 /// Inserts a value computed from `f` into the set if the given `value` is
910 /// not present, then returns a reference to the value in the set.
911 ///
912 /// # Examples
913 ///
914 /// ```
915 /// use hashbrown::HashSet;
916 ///
917 /// let mut set: HashSet<String> = ["cat", "dog", "horse"]
918 /// .iter().map(|&pet| pet.to_owned()).collect();
919 ///
920 /// assert_eq!(set.len(), 3);
921 /// for &pet in &["cat", "dog", "fish"] {
922 /// let value = set.get_or_insert_with(pet, str::to_owned);
923 /// assert_eq!(value, pet);
924 /// }
925 /// assert_eq!(set.len(), 4); // a new "fish" was inserted
926 /// ```
927 ///
928 /// The following example will panic because the new value doesn't match.
929 ///
930 /// ```should_panic
931 /// let mut set = hashbrown::HashSet::new();
932 /// set.get_or_insert_with("rust", |_| String::new());
933 /// ```
934 #[cfg_attr(feature = "inline-more", inline)]
935 pub fn get_or_insert_with<Q, F>(&mut self, value: &Q, f: F) -> &T
936 where
937 Q: Hash + Equivalent<T> + ?Sized,
938 F: FnOnce(&Q) -> T,
939 {
940 match self.map.entry_ref(value) {
941 map::EntryRef::Occupied(entry) => entry,
942 map::EntryRef::Vacant(entry) => entry.insert_entry_with_key(f(value), ()),
943 }
944 .into_entry()
945 .0
946 }
947
948 /// Gets the given value's corresponding entry in the set for in-place manipulation.
949 ///
950 /// # Examples
951 ///
952 /// ```
953 /// use hashbrown::HashSet;
954 /// use hashbrown::hash_set::Entry::*;
955 ///
956 /// let mut singles = HashSet::new();
957 /// let mut dupes = HashSet::new();
958 ///
959 /// for ch in "a short treatise on fungi".chars() {
960 /// if let Vacant(dupe_entry) = dupes.entry(ch) {
961 /// // We haven't already seen a duplicate, so
962 /// // check if we've at least seen it once.
963 /// match singles.entry(ch) {
964 /// Vacant(single_entry) => {
965 /// // We found a new character for the first time.
966 /// single_entry.insert();
967 /// }
968 /// Occupied(single_entry) => {
969 /// // We've already seen this once, "move" it to dupes.
970 /// single_entry.remove();
971 /// dupe_entry.insert();
972 /// }
973 /// }
974 /// }
975 /// }
976 ///
977 /// assert!(!singles.contains(&'t') && dupes.contains(&'t'));
978 /// assert!(singles.contains(&'u') && !dupes.contains(&'u'));
979 /// assert!(!singles.contains(&'v') && !dupes.contains(&'v'));
980 /// ```
981 #[cfg_attr(feature = "inline-more", inline)]
982 pub fn entry(&mut self, value: T) -> Entry<'_, T, S, A> {
983 match self.map.entry(value) {
984 map::Entry::Occupied(entry) => Entry::Occupied(OccupiedEntry { inner: entry }),
985 map::Entry::Vacant(entry) => Entry::Vacant(VacantEntry { inner: entry }),
986 }
987 }
988
989 /// Returns `true` if `self` has no elements in common with `other`.
990 /// This is equivalent to checking for an empty intersection.
991 ///
992 /// # Examples
993 ///
994 /// ```
995 /// use hashbrown::HashSet;
996 ///
997 /// let a: HashSet<_> = [1, 2, 3].into_iter().collect();
998 /// let mut b = HashSet::new();
999 ///
1000 /// assert_eq!(a.is_disjoint(&b), true);
1001 /// b.insert(4);
1002 /// assert_eq!(a.is_disjoint(&b), true);
1003 /// b.insert(1);
1004 /// assert_eq!(a.is_disjoint(&b), false);
1005 /// ```
1006 pub fn is_disjoint(&self, other: &Self) -> bool {
1007 self.intersection(other).next().is_none()
1008 }
1009
1010 /// Returns `true` if the set is a subset of another,
1011 /// i.e., `other` contains at least all the values in `self`.
1012 ///
1013 /// # Examples
1014 ///
1015 /// ```
1016 /// use hashbrown::HashSet;
1017 ///
1018 /// let sup: HashSet<_> = [1, 2, 3].into_iter().collect();
1019 /// let mut set = HashSet::new();
1020 ///
1021 /// assert_eq!(set.is_subset(&sup), true);
1022 /// set.insert(2);
1023 /// assert_eq!(set.is_subset(&sup), true);
1024 /// set.insert(4);
1025 /// assert_eq!(set.is_subset(&sup), false);
1026 /// ```
1027 pub fn is_subset(&self, other: &Self) -> bool {
1028 self.len() <= other.len() && self.iter().all(|v| other.contains(v))
1029 }
1030
1031 /// Returns `true` if the set is a superset of another,
1032 /// i.e., `self` contains at least all the values in `other`.
1033 ///
1034 /// # Examples
1035 ///
1036 /// ```
1037 /// use hashbrown::HashSet;
1038 ///
1039 /// let sub: HashSet<_> = [1, 2].into_iter().collect();
1040 /// let mut set = HashSet::new();
1041 ///
1042 /// assert_eq!(set.is_superset(&sub), false);
1043 ///
1044 /// set.insert(0);
1045 /// set.insert(1);
1046 /// assert_eq!(set.is_superset(&sub), false);
1047 ///
1048 /// set.insert(2);
1049 /// assert_eq!(set.is_superset(&sub), true);
1050 /// ```
1051 #[cfg_attr(feature = "inline-more", inline)]
1052 pub fn is_superset(&self, other: &Self) -> bool {
1053 other.is_subset(self)
1054 }
1055
1056 /// Adds a value to the set.
1057 ///
1058 /// If the set did not have this value present, `true` is returned.
1059 ///
1060 /// If the set did have this value present, `false` is returned.
1061 ///
1062 /// # Examples
1063 ///
1064 /// ```
1065 /// use hashbrown::HashSet;
1066 ///
1067 /// let mut set = HashSet::new();
1068 ///
1069 /// assert_eq!(set.insert(2), true);
1070 /// assert_eq!(set.insert(2), false);
1071 /// assert_eq!(set.len(), 1);
1072 /// ```
1073 #[cfg_attr(feature = "inline-more", inline)]
1074 pub fn insert(&mut self, value: T) -> bool {
1075 self.map.insert(value, ()).is_none()
1076 }
1077
1078 /// Insert a value the set without checking if the value already exists in the set.
1079 ///
1080 /// This operation is faster than regular insert, because it does not perform
1081 /// lookup before insertion.
1082 ///
1083 /// This operation is useful during initial population of the set.
1084 /// For example, when constructing a set from another set, we know
1085 /// that values are unique.
1086 ///
1087 /// # Safety
1088 ///
1089 /// This operation is safe if a value does not exist in the set.
1090 ///
1091 /// However, if a value exists in the set already, the behavior is unspecified:
1092 /// this operation may panic, loop forever, or any following operation with the set
1093 /// may panic, loop forever or return arbitrary result.
1094 ///
1095 /// That said, this operation (and following operations) are guaranteed to
1096 /// not violate memory safety.
1097 ///
1098 /// However this operation is still unsafe because the resulting `HashSet`
1099 /// may be passed to unsafe code which does expect the set to behave
1100 /// correctly, and would cause unsoundness as a result.
1101 #[cfg_attr(feature = "inline-more", inline)]
1102 pub unsafe fn insert_unique_unchecked(&mut self, value: T) -> &T {
1103 unsafe { self.map.insert_unique_unchecked(value, ()).0 }
1104 }
1105
1106 /// Adds a value to the set, replacing the existing value, if any, that is equal to the given
1107 /// one. Returns the replaced value.
1108 ///
1109 /// # Examples
1110 ///
1111 /// ```
1112 /// use hashbrown::HashSet;
1113 ///
1114 /// let mut set = HashSet::new();
1115 /// set.insert(Vec::<i32>::new());
1116 ///
1117 /// assert_eq!(set.get(&[][..]).unwrap().capacity(), 0);
1118 /// set.replace(Vec::with_capacity(10));
1119 /// assert_eq!(set.get(&[][..]).unwrap().capacity(), 10);
1120 /// ```
1121 #[cfg_attr(feature = "inline-more", inline)]
1122 pub fn replace(&mut self, value: T) -> Option<T> {
1123 let value = UnsafeCell::new(value);
1124 // SAFETY: We know the key is no longer accessed after the initial check.
1125 match self.map.entry_ref(unsafe { &*value.get() }) {
1126 map::EntryRef::Occupied(mut entry) => {
1127 // SAFETY: We know the key will not be accessed any more, and
1128 // that the key is equivalent to the one in the entry.
1129 Some(unsafe { entry.replace_key_unchecked(value.into_inner()) })
1130 }
1131 map::EntryRef::Vacant(entry) => {
1132 // SAFETY: A value is equivalent to itself.
1133 unsafe {
1134 entry.insert_with_key_unchecked(value.into_inner(), ());
1135 }
1136 None
1137 }
1138 }
1139 }
1140
1141 /// Removes a value from the set. Returns whether the value was
1142 /// present in the set.
1143 ///
1144 /// The value may be any borrowed form of the set's value type, but
1145 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1146 /// the value type.
1147 ///
1148 /// # Examples
1149 ///
1150 /// ```
1151 /// use hashbrown::HashSet;
1152 ///
1153 /// let mut set = HashSet::new();
1154 ///
1155 /// set.insert(2);
1156 /// assert_eq!(set.remove(&2), true);
1157 /// assert_eq!(set.remove(&2), false);
1158 /// ```
1159 ///
1160 #[cfg_attr(feature = "inline-more", inline)]
1161 pub fn remove<Q>(&mut self, value: &Q) -> bool
1162 where
1163 Q: Hash + Equivalent<T> + ?Sized,
1164 {
1165 self.map.remove(value).is_some()
1166 }
1167
1168 /// Removes and returns the value in the set, if any, that is equal to the given one.
1169 ///
1170 /// The value may be any borrowed form of the set's value type, but
1171 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1172 /// the value type.
1173 ///
1174 /// # Examples
1175 ///
1176 /// ```
1177 /// use hashbrown::HashSet;
1178 ///
1179 /// let mut set: HashSet<_> = [1, 2, 3].into_iter().collect();
1180 /// assert_eq!(set.take(&2), Some(2));
1181 /// assert_eq!(set.take(&2), None);
1182 /// ```
1183 ///
1184 #[cfg_attr(feature = "inline-more", inline)]
1185 pub fn take<Q>(&mut self, value: &Q) -> Option<T>
1186 where
1187 Q: Hash + Equivalent<T> + ?Sized,
1188 {
1189 // Avoid `Option::map` because it bloats LLVM IR.
1190 match self.map.remove_entry(value) {
1191 Some((k, _)) => Some(k),
1192 None => None,
1193 }
1194 }
1195
1196 /// Returns the total amount of memory allocated internally by the hash
1197 /// set, in bytes.
1198 ///
1199 /// The returned number is informational only. It is intended to be
1200 /// primarily used for memory profiling.
1201 #[inline]
1202 pub fn allocation_size(&self) -> usize {
1203 self.map.allocation_size()
1204 }
1205}
1206
1207impl<T, S, A> PartialEq for HashSet<T, S, A>
1208where
1209 T: Eq + Hash,
1210 S: BuildHasher,
1211 A: Allocator,
1212{
1213 fn eq(&self, other: &Self) -> bool {
1214 if self.len() != other.len() {
1215 return false;
1216 }
1217
1218 self.iter().all(|key| other.contains(key))
1219 }
1220}
1221
1222impl<T, S, A> Eq for HashSet<T, S, A>
1223where
1224 T: Eq + Hash,
1225 S: BuildHasher,
1226 A: Allocator,
1227{
1228}
1229
1230impl<T, S, A> fmt::Debug for HashSet<T, S, A>
1231where
1232 T: fmt::Debug,
1233 A: Allocator,
1234{
1235 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1236 f.debug_set().entries(self.iter()).finish()
1237 }
1238}
1239
1240impl<T, S, A> From<HashMap<T, (), S, A>> for HashSet<T, S, A>
1241where
1242 A: Allocator,
1243{
1244 fn from(map: HashMap<T, (), S, A>) -> Self {
1245 Self { map }
1246 }
1247}
1248
1249impl<T, S, A> FromIterator<T> for HashSet<T, S, A>
1250where
1251 T: Eq + Hash,
1252 S: BuildHasher + Default,
1253 A: Default + Allocator,
1254{
1255 #[cfg_attr(feature = "inline-more", inline)]
1256 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
1257 let mut set = Self::with_hasher_in(Default::default(), Default::default());
1258 set.extend(iter);
1259 set
1260 }
1261}
1262
1263// The default hasher is used to match the std implementation signature
1264#[cfg(feature = "default-hasher")]
1265impl<T, A, const N: usize> From<[T; N]> for HashSet<T, DefaultHashBuilder, A>
1266where
1267 T: Eq + Hash,
1268 A: Default + Allocator,
1269{
1270 /// # Examples
1271 ///
1272 /// ```
1273 /// use hashbrown::HashSet;
1274 ///
1275 /// let set1 = HashSet::from([1, 2, 3, 4]);
1276 /// let set2: HashSet<_> = [1, 2, 3, 4].into();
1277 /// assert_eq!(set1, set2);
1278 /// ```
1279 fn from(arr: [T; N]) -> Self {
1280 arr.into_iter().collect()
1281 }
1282}
1283
1284impl<T, S, A> Extend<T> for HashSet<T, S, A>
1285where
1286 T: Eq + Hash,
1287 S: BuildHasher,
1288 A: Allocator,
1289{
1290 #[cfg_attr(feature = "inline-more", inline)]
1291 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
1292 self.map.extend(iter.into_iter().map(|k| (k, ())));
1293 }
1294
1295 #[inline]
1296 #[cfg(feature = "nightly")]
1297 fn extend_one(&mut self, k: T) {
1298 self.map.insert(k, ());
1299 }
1300
1301 #[inline]
1302 #[cfg(feature = "nightly")]
1303 fn extend_reserve(&mut self, additional: usize) {
1304 Extend::<(T, ())>::extend_reserve(&mut self.map, additional);
1305 }
1306}
1307
1308impl<'a, T, S, A> Extend<&'a T> for HashSet<T, S, A>
1309where
1310 T: 'a + Eq + Hash + Copy,
1311 S: BuildHasher,
1312 A: Allocator,
1313{
1314 #[cfg_attr(feature = "inline-more", inline)]
1315 fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
1316 self.extend(iter.into_iter().copied());
1317 }
1318
1319 #[inline]
1320 #[cfg(feature = "nightly")]
1321 fn extend_one(&mut self, k: &'a T) {
1322 self.map.insert(*k, ());
1323 }
1324
1325 #[inline]
1326 #[cfg(feature = "nightly")]
1327 fn extend_reserve(&mut self, additional: usize) {
1328 Extend::<(T, ())>::extend_reserve(&mut self.map, additional);
1329 }
1330}
1331
1332impl<T, S, A> Default for HashSet<T, S, A>
1333where
1334 S: Default,
1335 A: Default + Allocator,
1336{
1337 /// Creates an empty `HashSet<T, S>` with the `Default` value for the hasher.
1338 #[cfg_attr(feature = "inline-more", inline)]
1339 fn default() -> Self {
1340 Self {
1341 map: HashMap::default(),
1342 }
1343 }
1344}
1345
1346impl<T, S, A> BitOr<&HashSet<T, S, A>> for &HashSet<T, S, A>
1347where
1348 T: Eq + Hash + Clone,
1349 S: BuildHasher + Default,
1350 A: Allocator + Default,
1351{
1352 type Output = HashSet<T, S, A>;
1353
1354 /// Returns the union of `self` and `rhs` as a new `HashSet<T, S>`.
1355 ///
1356 /// # Examples
1357 ///
1358 /// ```
1359 /// use hashbrown::HashSet;
1360 ///
1361 /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
1362 /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
1363 ///
1364 /// let set = &a | &b;
1365 ///
1366 /// let mut i = 0;
1367 /// let expected = [1, 2, 3, 4, 5];
1368 /// for x in &set {
1369 /// assert!(expected.contains(x));
1370 /// i += 1;
1371 /// }
1372 /// assert_eq!(i, expected.len());
1373 /// ```
1374 fn bitor(self, rhs: &HashSet<T, S, A>) -> HashSet<T, S, A> {
1375 self.union(rhs).cloned().collect()
1376 }
1377}
1378
1379impl<T, S, A> BitAnd<&HashSet<T, S, A>> for &HashSet<T, S, A>
1380where
1381 T: Eq + Hash + Clone,
1382 S: BuildHasher + Default,
1383 A: Allocator + Default,
1384{
1385 type Output = HashSet<T, S, A>;
1386
1387 /// Returns the intersection of `self` and `rhs` as a new `HashSet<T, S>`.
1388 ///
1389 /// # Examples
1390 ///
1391 /// ```
1392 /// use hashbrown::HashSet;
1393 ///
1394 /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
1395 /// let b: HashSet<_> = vec![2, 3, 4].into_iter().collect();
1396 ///
1397 /// let set = &a & &b;
1398 ///
1399 /// let mut i = 0;
1400 /// let expected = [2, 3];
1401 /// for x in &set {
1402 /// assert!(expected.contains(x));
1403 /// i += 1;
1404 /// }
1405 /// assert_eq!(i, expected.len());
1406 /// ```
1407 fn bitand(self, rhs: &HashSet<T, S, A>) -> HashSet<T, S, A> {
1408 self.intersection(rhs).cloned().collect()
1409 }
1410}
1411
1412impl<T, S, A> BitXor<&HashSet<T, S, A>> for &HashSet<T, S, A>
1413where
1414 T: Eq + Hash + Clone,
1415 S: BuildHasher + Default,
1416 A: Allocator + Default,
1417{
1418 type Output = HashSet<T, S, A>;
1419
1420 /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet<T, S>`.
1421 ///
1422 /// # Examples
1423 ///
1424 /// ```
1425 /// use hashbrown::HashSet;
1426 ///
1427 /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
1428 /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
1429 ///
1430 /// let set = &a ^ &b;
1431 ///
1432 /// let mut i = 0;
1433 /// let expected = [1, 2, 4, 5];
1434 /// for x in &set {
1435 /// assert!(expected.contains(x));
1436 /// i += 1;
1437 /// }
1438 /// assert_eq!(i, expected.len());
1439 /// ```
1440 fn bitxor(self, rhs: &HashSet<T, S, A>) -> HashSet<T, S, A> {
1441 self.symmetric_difference(rhs).cloned().collect()
1442 }
1443}
1444
1445impl<T, S, A> Sub<&HashSet<T, S, A>> for &HashSet<T, S, A>
1446where
1447 T: Eq + Hash + Clone,
1448 S: BuildHasher + Default,
1449 A: Allocator + Default,
1450{
1451 type Output = HashSet<T, S, A>;
1452
1453 /// Returns the difference of `self` and `rhs` as a new `HashSet<T, S>`.
1454 ///
1455 /// # Examples
1456 ///
1457 /// ```
1458 /// use hashbrown::HashSet;
1459 ///
1460 /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
1461 /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
1462 ///
1463 /// let set = &a - &b;
1464 ///
1465 /// let mut i = 0;
1466 /// let expected = [1, 2];
1467 /// for x in &set {
1468 /// assert!(expected.contains(x));
1469 /// i += 1;
1470 /// }
1471 /// assert_eq!(i, expected.len());
1472 /// ```
1473 fn sub(self, rhs: &HashSet<T, S, A>) -> HashSet<T, S, A> {
1474 self.difference(rhs).cloned().collect()
1475 }
1476}
1477
1478impl<T, S, A> BitOrAssign<&HashSet<T, S, A>> for HashSet<T, S, A>
1479where
1480 T: Eq + Hash + Clone,
1481 S: BuildHasher,
1482 A: Allocator,
1483{
1484 /// Modifies this set to contain the union of `self` and `rhs`.
1485 ///
1486 /// # Examples
1487 ///
1488 /// ```
1489 /// use hashbrown::HashSet;
1490 ///
1491 /// let mut a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
1492 /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
1493 ///
1494 /// a |= &b;
1495 ///
1496 /// let mut i = 0;
1497 /// let expected = [1, 2, 3, 4, 5];
1498 /// for x in &a {
1499 /// assert!(expected.contains(x));
1500 /// i += 1;
1501 /// }
1502 /// assert_eq!(i, expected.len());
1503 /// ```
1504 fn bitor_assign(&mut self, rhs: &HashSet<T, S, A>) {
1505 for item in rhs {
1506 if !self.contains(item) {
1507 self.insert(item.clone());
1508 }
1509 }
1510 }
1511}
1512
1513impl<T, S, A> BitAndAssign<&HashSet<T, S, A>> for HashSet<T, S, A>
1514where
1515 T: Eq + Hash + Clone,
1516 S: BuildHasher,
1517 A: Allocator,
1518{
1519 /// Modifies this set to contain the intersection of `self` and `rhs`.
1520 ///
1521 /// # Examples
1522 ///
1523 /// ```
1524 /// use hashbrown::HashSet;
1525 ///
1526 /// let mut a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
1527 /// let b: HashSet<_> = vec![2, 3, 4].into_iter().collect();
1528 ///
1529 /// a &= &b;
1530 ///
1531 /// let mut i = 0;
1532 /// let expected = [2, 3];
1533 /// for x in &a {
1534 /// assert!(expected.contains(x));
1535 /// i += 1;
1536 /// }
1537 /// assert_eq!(i, expected.len());
1538 /// ```
1539 fn bitand_assign(&mut self, rhs: &HashSet<T, S, A>) {
1540 self.retain(|item| rhs.contains(item));
1541 }
1542}
1543
1544impl<T, S, A> BitXorAssign<&HashSet<T, S, A>> for HashSet<T, S, A>
1545where
1546 T: Eq + Hash + Clone,
1547 S: BuildHasher,
1548 A: Allocator,
1549{
1550 /// Modifies this set to contain the symmetric difference of `self` and `rhs`.
1551 ///
1552 /// # Examples
1553 ///
1554 /// ```
1555 /// use hashbrown::HashSet;
1556 ///
1557 /// let mut a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
1558 /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
1559 ///
1560 /// a ^= &b;
1561 ///
1562 /// let mut i = 0;
1563 /// let expected = [1, 2, 4, 5];
1564 /// for x in &a {
1565 /// assert!(expected.contains(x));
1566 /// i += 1;
1567 /// }
1568 /// assert_eq!(i, expected.len());
1569 /// ```
1570 fn bitxor_assign(&mut self, rhs: &HashSet<T, S, A>) {
1571 for item in rhs {
1572 match self.map.entry_ref(item) {
1573 map::EntryRef::Occupied(entry) => {
1574 entry.remove();
1575 }
1576 map::EntryRef::Vacant(entry) => {
1577 entry.insert(());
1578 }
1579 }
1580 }
1581 }
1582}
1583
1584impl<T, S, A> SubAssign<&HashSet<T, S, A>> for HashSet<T, S, A>
1585where
1586 T: Eq + Hash + Clone,
1587 S: BuildHasher,
1588 A: Allocator,
1589{
1590 /// Modifies this set to contain the difference of `self` and `rhs`.
1591 ///
1592 /// # Examples
1593 ///
1594 /// ```
1595 /// use hashbrown::HashSet;
1596 ///
1597 /// let mut a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
1598 /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
1599 ///
1600 /// a -= &b;
1601 ///
1602 /// let mut i = 0;
1603 /// let expected = [1, 2];
1604 /// for x in &a {
1605 /// assert!(expected.contains(x));
1606 /// i += 1;
1607 /// }
1608 /// assert_eq!(i, expected.len());
1609 /// ```
1610 fn sub_assign(&mut self, rhs: &HashSet<T, S, A>) {
1611 if rhs.len() < self.len() {
1612 for item in rhs {
1613 self.remove(item);
1614 }
1615 } else {
1616 self.retain(|item| !rhs.contains(item));
1617 }
1618 }
1619}
1620
1621/// An iterator over the items of a `HashSet`.
1622///
1623/// This `struct` is created by the [`iter`] method on [`HashSet`].
1624/// See its documentation for more.
1625///
1626/// [`iter`]: HashSet::iter
1627pub struct Iter<'a, K> {
1628 iter: Keys<'a, K, ()>,
1629}
1630
1631/// An owning iterator over the items of a `HashSet`.
1632///
1633/// This `struct` is created by the [`into_iter`] method on [`HashSet`]
1634/// (provided by the `IntoIterator` trait). See its documentation for more.
1635///
1636/// [`into_iter`]: HashSet::into_iter
1637pub struct IntoIter<K, A: Allocator = Global> {
1638 iter: map::IntoIter<K, (), A>,
1639}
1640
1641/// A draining iterator over the items of a `HashSet`.
1642///
1643/// This `struct` is created by the [`drain`] method on [`HashSet`].
1644/// See its documentation for more.
1645///
1646/// [`drain`]: HashSet::drain
1647pub struct Drain<'a, K, A: Allocator = Global> {
1648 iter: map::Drain<'a, K, (), A>,
1649}
1650
1651/// A draining iterator over entries of a `HashSet` which don't satisfy the predicate `f`.
1652///
1653/// This `struct` is created by the [`extract_if`] method on [`HashSet`]. See its
1654/// documentation for more.
1655///
1656/// [`extract_if`]: HashSet::extract_if
1657#[must_use = "Iterators are lazy unless consumed"]
1658pub struct ExtractIf<'a, K, F, A: Allocator = Global> {
1659 f: F,
1660 inner: RawExtractIf<'a, (K, ()), A>,
1661}
1662
1663/// A lazy iterator producing elements in the intersection of `HashSet`s.
1664///
1665/// This `struct` is created by the [`intersection`] method on [`HashSet`].
1666/// See its documentation for more.
1667///
1668/// [`intersection`]: HashSet::intersection
1669pub struct Intersection<'a, T, S, A: Allocator = Global> {
1670 // iterator of the first set
1671 iter: Iter<'a, T>,
1672 // the second set
1673 other: &'a HashSet<T, S, A>,
1674}
1675
1676/// A lazy iterator producing elements in the difference of `HashSet`s.
1677///
1678/// This `struct` is created by the [`difference`] method on [`HashSet`].
1679/// See its documentation for more.
1680///
1681/// [`difference`]: HashSet::difference
1682pub struct Difference<'a, T, S, A: Allocator = Global> {
1683 // iterator of the first set
1684 iter: Iter<'a, T>,
1685 // the second set
1686 other: &'a HashSet<T, S, A>,
1687}
1688
1689/// A lazy iterator producing elements in the symmetric difference of `HashSet`s.
1690///
1691/// This `struct` is created by the [`symmetric_difference`] method on
1692/// [`HashSet`]. See its documentation for more.
1693///
1694/// [`symmetric_difference`]: HashSet::symmetric_difference
1695pub struct SymmetricDifference<'a, T, S, A: Allocator = Global> {
1696 iter: Chain<Difference<'a, T, S, A>, Difference<'a, T, S, A>>,
1697}
1698
1699/// A lazy iterator producing elements in the union of `HashSet`s.
1700///
1701/// This `struct` is created by the [`union`] method on [`HashSet`].
1702/// See its documentation for more.
1703///
1704/// [`union`]: HashSet::union
1705pub struct Union<'a, T, S, A: Allocator = Global> {
1706 iter: Chain<Iter<'a, T>, Difference<'a, T, S, A>>,
1707}
1708
1709impl<'a, T, S, A: Allocator> IntoIterator for &'a HashSet<T, S, A> {
1710 type Item = &'a T;
1711 type IntoIter = Iter<'a, T>;
1712
1713 #[cfg_attr(feature = "inline-more", inline)]
1714 fn into_iter(self) -> Iter<'a, T> {
1715 self.iter()
1716 }
1717}
1718
1719impl<T, S, A: Allocator> IntoIterator for HashSet<T, S, A> {
1720 type Item = T;
1721 type IntoIter = IntoIter<T, A>;
1722
1723 /// Creates a consuming iterator, that is, one that moves each value out
1724 /// of the set in arbitrary order. The set cannot be used after calling
1725 /// this.
1726 ///
1727 /// # Examples
1728 ///
1729 /// ```
1730 /// use hashbrown::HashSet;
1731 /// let mut set = HashSet::new();
1732 /// set.insert("a".to_string());
1733 /// set.insert("b".to_string());
1734 ///
1735 /// // Not possible to collect to a Vec<String> with a regular `.iter()`.
1736 /// let v: Vec<String> = set.into_iter().collect();
1737 ///
1738 /// // Will print in an arbitrary order.
1739 /// for x in &v {
1740 /// println!("{}", x);
1741 /// }
1742 /// ```
1743 #[cfg_attr(feature = "inline-more", inline)]
1744 fn into_iter(self) -> IntoIter<T, A> {
1745 IntoIter {
1746 iter: self.map.into_iter(),
1747 }
1748 }
1749}
1750
1751impl<K> Clone for Iter<'_, K> {
1752 #[cfg_attr(feature = "inline-more", inline)]
1753 fn clone(&self) -> Self {
1754 Iter {
1755 iter: self.iter.clone(),
1756 }
1757 }
1758}
1759impl<K> Default for Iter<'_, K> {
1760 #[cfg_attr(feature = "inline-more", inline)]
1761 fn default() -> Self {
1762 Iter {
1763 iter: Default::default(),
1764 }
1765 }
1766}
1767impl<'a, K> Iterator for Iter<'a, K> {
1768 type Item = &'a K;
1769
1770 #[cfg_attr(feature = "inline-more", inline)]
1771 fn next(&mut self) -> Option<&'a K> {
1772 self.iter.next()
1773 }
1774 #[cfg_attr(feature = "inline-more", inline)]
1775 fn size_hint(&self) -> (usize, Option<usize>) {
1776 self.iter.size_hint()
1777 }
1778 #[cfg_attr(feature = "inline-more", inline)]
1779 fn fold<B, F>(self, init: B, f: F) -> B
1780 where
1781 Self: Sized,
1782 F: FnMut(B, Self::Item) -> B,
1783 {
1784 self.iter.fold(init, f)
1785 }
1786}
1787impl<K> ExactSizeIterator for Iter<'_, K> {
1788 #[cfg_attr(feature = "inline-more", inline)]
1789 fn len(&self) -> usize {
1790 self.iter.len()
1791 }
1792}
1793impl<K> FusedIterator for Iter<'_, K> {}
1794
1795impl<K: fmt::Debug> fmt::Debug for Iter<'_, K> {
1796 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1797 f.debug_list().entries(self.clone()).finish()
1798 }
1799}
1800
1801impl<K, A: Allocator> Default for IntoIter<K, A> {
1802 #[cfg_attr(feature = "inline-more", inline)]
1803 fn default() -> Self {
1804 IntoIter {
1805 iter: Default::default(),
1806 }
1807 }
1808}
1809impl<K, A: Allocator> Iterator for IntoIter<K, A> {
1810 type Item = K;
1811
1812 #[cfg_attr(feature = "inline-more", inline)]
1813 fn next(&mut self) -> Option<K> {
1814 // Avoid `Option::map` because it bloats LLVM IR.
1815 match self.iter.next() {
1816 Some((k, _)) => Some(k),
1817 None => None,
1818 }
1819 }
1820 #[cfg_attr(feature = "inline-more", inline)]
1821 fn size_hint(&self) -> (usize, Option<usize>) {
1822 self.iter.size_hint()
1823 }
1824 #[cfg_attr(feature = "inline-more", inline)]
1825 fn fold<B, F>(self, init: B, mut f: F) -> B
1826 where
1827 Self: Sized,
1828 F: FnMut(B, Self::Item) -> B,
1829 {
1830 self.iter.fold(init, |acc, (k, ())| f(acc, k))
1831 }
1832}
1833impl<K, A: Allocator> ExactSizeIterator for IntoIter<K, A> {
1834 #[cfg_attr(feature = "inline-more", inline)]
1835 fn len(&self) -> usize {
1836 self.iter.len()
1837 }
1838}
1839impl<K, A: Allocator> FusedIterator for IntoIter<K, A> {}
1840
1841impl<K: fmt::Debug, A: Allocator> fmt::Debug for IntoIter<K, A> {
1842 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1843 let entries_iter = self.iter.iter().map(|(k, _)| k);
1844 f.debug_list().entries(entries_iter).finish()
1845 }
1846}
1847
1848impl<K, A: Allocator> Iterator for Drain<'_, K, A> {
1849 type Item = K;
1850
1851 #[cfg_attr(feature = "inline-more", inline)]
1852 fn next(&mut self) -> Option<K> {
1853 // Avoid `Option::map` because it bloats LLVM IR.
1854 match self.iter.next() {
1855 Some((k, _)) => Some(k),
1856 None => None,
1857 }
1858 }
1859 #[cfg_attr(feature = "inline-more", inline)]
1860 fn size_hint(&self) -> (usize, Option<usize>) {
1861 self.iter.size_hint()
1862 }
1863 #[cfg_attr(feature = "inline-more", inline)]
1864 fn fold<B, F>(self, init: B, mut f: F) -> B
1865 where
1866 Self: Sized,
1867 F: FnMut(B, Self::Item) -> B,
1868 {
1869 self.iter.fold(init, |acc, (k, ())| f(acc, k))
1870 }
1871}
1872impl<K, A: Allocator> ExactSizeIterator for Drain<'_, K, A> {
1873 #[cfg_attr(feature = "inline-more", inline)]
1874 fn len(&self) -> usize {
1875 self.iter.len()
1876 }
1877}
1878impl<K, A: Allocator> FusedIterator for Drain<'_, K, A> {}
1879
1880impl<K: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, K, A> {
1881 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1882 let entries_iter = self.iter.iter().map(|(k, _)| k);
1883 f.debug_list().entries(entries_iter).finish()
1884 }
1885}
1886
1887impl<K, F, A: Allocator> Iterator for ExtractIf<'_, K, F, A>
1888where
1889 F: FnMut(&K) -> bool,
1890{
1891 type Item = K;
1892
1893 #[cfg_attr(feature = "inline-more", inline)]
1894 fn next(&mut self) -> Option<Self::Item> {
1895 self.inner
1896 .next(|&mut (ref k, ())| (self.f)(k))
1897 .map(|(k, ())| k)
1898 }
1899
1900 #[inline]
1901 fn size_hint(&self) -> (usize, Option<usize>) {
1902 (0, self.inner.iter.size_hint().1)
1903 }
1904}
1905
1906impl<K, F, A: Allocator> FusedIterator for ExtractIf<'_, K, F, A> where F: FnMut(&K) -> bool {}
1907
1908impl<T, S, A: Allocator> Clone for Intersection<'_, T, S, A> {
1909 #[cfg_attr(feature = "inline-more", inline)]
1910 fn clone(&self) -> Self {
1911 Intersection {
1912 iter: self.iter.clone(),
1913 ..*self
1914 }
1915 }
1916}
1917
1918impl<'a, T, S, A> Iterator for Intersection<'a, T, S, A>
1919where
1920 T: Eq + Hash,
1921 S: BuildHasher,
1922 A: Allocator,
1923{
1924 type Item = &'a T;
1925
1926 #[cfg_attr(feature = "inline-more", inline)]
1927 fn next(&mut self) -> Option<&'a T> {
1928 loop {
1929 let elt = self.iter.next()?;
1930 if self.other.contains(elt) {
1931 return Some(elt);
1932 }
1933 }
1934 }
1935
1936 #[cfg_attr(feature = "inline-more", inline)]
1937 fn size_hint(&self) -> (usize, Option<usize>) {
1938 let (_, upper) = self.iter.size_hint();
1939 (0, upper)
1940 }
1941
1942 #[cfg_attr(feature = "inline-more", inline)]
1943 fn fold<B, F>(self, init: B, mut f: F) -> B
1944 where
1945 Self: Sized,
1946 F: FnMut(B, Self::Item) -> B,
1947 {
1948 self.iter.fold(init, |acc, elt| {
1949 if self.other.contains(elt) {
1950 f(acc, elt)
1951 } else {
1952 acc
1953 }
1954 })
1955 }
1956}
1957
1958impl<T, S, A> fmt::Debug for Intersection<'_, T, S, A>
1959where
1960 T: fmt::Debug + Eq + Hash,
1961 S: BuildHasher,
1962 A: Allocator,
1963{
1964 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1965 f.debug_list().entries(self.clone()).finish()
1966 }
1967}
1968
1969impl<T, S, A> FusedIterator for Intersection<'_, T, S, A>
1970where
1971 T: Eq + Hash,
1972 S: BuildHasher,
1973 A: Allocator,
1974{
1975}
1976
1977impl<T, S, A: Allocator> Clone for Difference<'_, T, S, A> {
1978 #[cfg_attr(feature = "inline-more", inline)]
1979 fn clone(&self) -> Self {
1980 Difference {
1981 iter: self.iter.clone(),
1982 ..*self
1983 }
1984 }
1985}
1986
1987impl<'a, T, S, A> Iterator for Difference<'a, T, S, A>
1988where
1989 T: Eq + Hash,
1990 S: BuildHasher,
1991 A: Allocator,
1992{
1993 type Item = &'a T;
1994
1995 #[cfg_attr(feature = "inline-more", inline)]
1996 fn next(&mut self) -> Option<&'a T> {
1997 loop {
1998 let elt = self.iter.next()?;
1999 if !self.other.contains(elt) {
2000 return Some(elt);
2001 }
2002 }
2003 }
2004
2005 #[cfg_attr(feature = "inline-more", inline)]
2006 fn size_hint(&self) -> (usize, Option<usize>) {
2007 let (lower, upper) = self.iter.size_hint();
2008 (lower.saturating_sub(self.other.len()), upper)
2009 }
2010
2011 #[cfg_attr(feature = "inline-more", inline)]
2012 fn fold<B, F>(self, init: B, mut f: F) -> B
2013 where
2014 Self: Sized,
2015 F: FnMut(B, Self::Item) -> B,
2016 {
2017 self.iter.fold(init, |acc, elt| {
2018 if self.other.contains(elt) {
2019 acc
2020 } else {
2021 f(acc, elt)
2022 }
2023 })
2024 }
2025}
2026
2027impl<T, S, A> FusedIterator for Difference<'_, T, S, A>
2028where
2029 T: Eq + Hash,
2030 S: BuildHasher,
2031 A: Allocator,
2032{
2033}
2034
2035impl<T, S, A> fmt::Debug for Difference<'_, T, S, A>
2036where
2037 T: fmt::Debug + Eq + Hash,
2038 S: BuildHasher,
2039 A: Allocator,
2040{
2041 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2042 f.debug_list().entries(self.clone()).finish()
2043 }
2044}
2045
2046impl<T, S, A: Allocator> Clone for SymmetricDifference<'_, T, S, A> {
2047 #[cfg_attr(feature = "inline-more", inline)]
2048 fn clone(&self) -> Self {
2049 SymmetricDifference {
2050 iter: self.iter.clone(),
2051 }
2052 }
2053}
2054
2055impl<'a, T, S, A> Iterator for SymmetricDifference<'a, T, S, A>
2056where
2057 T: Eq + Hash,
2058 S: BuildHasher,
2059 A: Allocator,
2060{
2061 type Item = &'a T;
2062
2063 #[cfg_attr(feature = "inline-more", inline)]
2064 fn next(&mut self) -> Option<&'a T> {
2065 self.iter.next()
2066 }
2067
2068 #[cfg_attr(feature = "inline-more", inline)]
2069 fn size_hint(&self) -> (usize, Option<usize>) {
2070 self.iter.size_hint()
2071 }
2072
2073 #[cfg_attr(feature = "inline-more", inline)]
2074 fn fold<B, F>(self, init: B, f: F) -> B
2075 where
2076 Self: Sized,
2077 F: FnMut(B, Self::Item) -> B,
2078 {
2079 self.iter.fold(init, f)
2080 }
2081}
2082
2083impl<T, S, A> FusedIterator for SymmetricDifference<'_, T, S, A>
2084where
2085 T: Eq + Hash,
2086 S: BuildHasher,
2087 A: Allocator,
2088{
2089}
2090
2091impl<T, S, A> fmt::Debug for SymmetricDifference<'_, T, S, A>
2092where
2093 T: fmt::Debug + Eq + Hash,
2094 S: BuildHasher,
2095 A: Allocator,
2096{
2097 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2098 f.debug_list().entries(self.clone()).finish()
2099 }
2100}
2101
2102impl<T, S, A: Allocator> Clone for Union<'_, T, S, A> {
2103 #[cfg_attr(feature = "inline-more", inline)]
2104 fn clone(&self) -> Self {
2105 Union {
2106 iter: self.iter.clone(),
2107 }
2108 }
2109}
2110
2111impl<T, S, A> FusedIterator for Union<'_, T, S, A>
2112where
2113 T: Eq + Hash,
2114 S: BuildHasher,
2115 A: Allocator,
2116{
2117}
2118
2119impl<T, S, A> fmt::Debug for Union<'_, T, S, A>
2120where
2121 T: fmt::Debug + Eq + Hash,
2122 S: BuildHasher,
2123 A: Allocator,
2124{
2125 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2126 f.debug_list().entries(self.clone()).finish()
2127 }
2128}
2129
2130impl<'a, T, S, A> Iterator for Union<'a, T, S, A>
2131where
2132 T: Eq + Hash,
2133 S: BuildHasher,
2134 A: Allocator,
2135{
2136 type Item = &'a T;
2137
2138 #[cfg_attr(feature = "inline-more", inline)]
2139 fn next(&mut self) -> Option<&'a T> {
2140 self.iter.next()
2141 }
2142
2143 #[cfg_attr(feature = "inline-more", inline)]
2144 fn size_hint(&self) -> (usize, Option<usize>) {
2145 self.iter.size_hint()
2146 }
2147
2148 #[cfg_attr(feature = "inline-more", inline)]
2149 fn fold<B, F>(self, init: B, f: F) -> B
2150 where
2151 Self: Sized,
2152 F: FnMut(B, Self::Item) -> B,
2153 {
2154 self.iter.fold(init, f)
2155 }
2156}
2157
2158/// A view into a single entry in a set, which may either be vacant or occupied.
2159///
2160/// This `enum` is constructed from the [`entry`] method on [`HashSet`].
2161///
2162/// [`entry`]: HashSet::entry
2163///
2164/// # Examples
2165///
2166/// ```
2167/// use hashbrown::hash_set::{Entry, HashSet, OccupiedEntry};
2168///
2169/// let mut set = HashSet::new();
2170/// set.extend(["a", "b", "c"]);
2171/// assert_eq!(set.len(), 3);
2172///
2173/// // Existing value (insert)
2174/// let entry: Entry<_, _> = set.entry("a");
2175/// let _raw_o: OccupiedEntry<_, _> = entry.insert();
2176/// assert_eq!(set.len(), 3);
2177/// // Nonexistent value (insert)
2178/// set.entry("d").insert();
2179///
2180/// // Existing value (or_insert)
2181/// set.entry("b").or_insert();
2182/// // Nonexistent value (or_insert)
2183/// set.entry("e").or_insert();
2184///
2185/// println!("Our HashSet: {:?}", set);
2186///
2187/// let mut vec: Vec<_> = set.iter().copied().collect();
2188/// // The `Iter` iterator produces items in arbitrary order, so the
2189/// // items must be sorted to test them against a sorted array.
2190/// vec.sort_unstable();
2191/// assert_eq!(vec, ["a", "b", "c", "d", "e"]);
2192/// ```
2193pub enum Entry<'a, T, S, A = Global>
2194where
2195 A: Allocator,
2196{
2197 /// An occupied entry.
2198 ///
2199 /// # Examples
2200 ///
2201 /// ```
2202 /// use hashbrown::hash_set::{Entry, HashSet};
2203 /// let mut set: HashSet<_> = ["a", "b"].into();
2204 ///
2205 /// match set.entry("a") {
2206 /// Entry::Vacant(_) => unreachable!(),
2207 /// Entry::Occupied(_) => { }
2208 /// }
2209 /// ```
2210 Occupied(OccupiedEntry<'a, T, S, A>),
2211
2212 /// A vacant entry.
2213 ///
2214 /// # Examples
2215 ///
2216 /// ```
2217 /// use hashbrown::hash_set::{Entry, HashSet};
2218 /// let mut set: HashSet<&str> = HashSet::new();
2219 ///
2220 /// match set.entry("a") {
2221 /// Entry::Occupied(_) => unreachable!(),
2222 /// Entry::Vacant(_) => { }
2223 /// }
2224 /// ```
2225 Vacant(VacantEntry<'a, T, S, A>),
2226}
2227
2228impl<T: fmt::Debug, S, A: Allocator> fmt::Debug for Entry<'_, T, S, A> {
2229 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2230 match *self {
2231 Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
2232 Entry::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
2233 }
2234 }
2235}
2236
2237/// A view into an occupied entry in a `HashSet`.
2238/// It is part of the [`Entry`] enum.
2239///
2240/// # Examples
2241///
2242/// ```
2243/// use hashbrown::hash_set::{Entry, HashSet, OccupiedEntry};
2244///
2245/// let mut set = HashSet::new();
2246/// set.extend(["a", "b", "c"]);
2247///
2248/// let _entry_o: OccupiedEntry<_, _> = set.entry("a").insert();
2249/// assert_eq!(set.len(), 3);
2250///
2251/// // Existing key
2252/// match set.entry("a") {
2253/// Entry::Vacant(_) => unreachable!(),
2254/// Entry::Occupied(view) => {
2255/// assert_eq!(view.get(), &"a");
2256/// }
2257/// }
2258///
2259/// assert_eq!(set.len(), 3);
2260///
2261/// // Existing key (take)
2262/// match set.entry("c") {
2263/// Entry::Vacant(_) => unreachable!(),
2264/// Entry::Occupied(view) => {
2265/// assert_eq!(view.remove(), "c");
2266/// }
2267/// }
2268/// assert_eq!(set.get(&"c"), None);
2269/// assert_eq!(set.len(), 2);
2270/// ```
2271pub struct OccupiedEntry<'a, T, S, A: Allocator = Global> {
2272 inner: map::OccupiedEntry<'a, T, (), S, A>,
2273}
2274
2275impl<T: fmt::Debug, S, A: Allocator> fmt::Debug for OccupiedEntry<'_, T, S, A> {
2276 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2277 f.debug_struct("OccupiedEntry")
2278 .field("value", self.get())
2279 .finish()
2280 }
2281}
2282
2283/// A view into a vacant entry in a `HashSet`.
2284/// It is part of the [`Entry`] enum.
2285///
2286/// # Examples
2287///
2288/// ```
2289/// use hashbrown::hash_set::{Entry, HashSet, VacantEntry};
2290///
2291/// let mut set = HashSet::<&str>::new();
2292///
2293/// let entry_v: VacantEntry<_, _> = match set.entry("a") {
2294/// Entry::Vacant(view) => view,
2295/// Entry::Occupied(_) => unreachable!(),
2296/// };
2297/// entry_v.insert();
2298/// assert!(set.contains("a") && set.len() == 1);
2299///
2300/// // Nonexistent key (insert)
2301/// match set.entry("b") {
2302/// Entry::Vacant(view) => { view.insert(); },
2303/// Entry::Occupied(_) => unreachable!(),
2304/// }
2305/// assert!(set.contains("b") && set.len() == 2);
2306/// ```
2307pub struct VacantEntry<'a, T, S, A: Allocator = Global> {
2308 inner: map::VacantEntry<'a, T, (), S, A>,
2309}
2310
2311impl<T: fmt::Debug, S, A: Allocator> fmt::Debug for VacantEntry<'_, T, S, A> {
2312 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2313 f.debug_tuple("VacantEntry").field(self.get()).finish()
2314 }
2315}
2316
2317impl<'a, T, S, A: Allocator> Entry<'a, T, S, A> {
2318 /// Sets the value of the entry, and returns an `OccupiedEntry`.
2319 ///
2320 /// # Examples
2321 ///
2322 /// ```
2323 /// use hashbrown::HashSet;
2324 ///
2325 /// let mut set: HashSet<&str> = HashSet::new();
2326 /// let entry = set.entry("horseyland").insert();
2327 ///
2328 /// assert_eq!(entry.get(), &"horseyland");
2329 /// ```
2330 #[cfg_attr(feature = "inline-more", inline)]
2331 pub fn insert(self) -> OccupiedEntry<'a, T, S, A>
2332 where
2333 T: Hash,
2334 S: BuildHasher,
2335 {
2336 match self {
2337 Entry::Occupied(entry) => entry,
2338 Entry::Vacant(entry) => entry.insert(),
2339 }
2340 }
2341
2342 /// Ensures a value is in the entry by inserting if it was vacant.
2343 ///
2344 /// # Examples
2345 ///
2346 /// ```
2347 /// use hashbrown::HashSet;
2348 ///
2349 /// let mut set: HashSet<&str> = HashSet::new();
2350 ///
2351 /// // nonexistent key
2352 /// set.entry("poneyland").or_insert();
2353 /// assert!(set.contains("poneyland"));
2354 ///
2355 /// // existing key
2356 /// set.entry("poneyland").or_insert();
2357 /// assert!(set.contains("poneyland"));
2358 /// assert_eq!(set.len(), 1);
2359 /// ```
2360 #[cfg_attr(feature = "inline-more", inline)]
2361 pub fn or_insert(self)
2362 where
2363 T: Hash,
2364 S: BuildHasher,
2365 {
2366 if let Entry::Vacant(entry) = self {
2367 entry.insert();
2368 }
2369 }
2370
2371 /// Returns a reference to this entry's value.
2372 ///
2373 /// # Examples
2374 ///
2375 /// ```
2376 /// use hashbrown::HashSet;
2377 ///
2378 /// let mut set: HashSet<&str> = HashSet::new();
2379 /// set.entry("poneyland").or_insert();
2380 /// // existing key
2381 /// assert_eq!(set.entry("poneyland").get(), &"poneyland");
2382 /// // nonexistent key
2383 /// assert_eq!(set.entry("horseland").get(), &"horseland");
2384 /// ```
2385 #[cfg_attr(feature = "inline-more", inline)]
2386 pub fn get(&self) -> &T {
2387 match *self {
2388 Entry::Occupied(ref entry) => entry.get(),
2389 Entry::Vacant(ref entry) => entry.get(),
2390 }
2391 }
2392}
2393
2394impl<T, S, A: Allocator> OccupiedEntry<'_, T, S, A> {
2395 /// Gets a reference to the value in the entry.
2396 ///
2397 /// # Examples
2398 ///
2399 /// ```
2400 /// use hashbrown::hash_set::{Entry, HashSet};
2401 ///
2402 /// let mut set: HashSet<&str> = HashSet::new();
2403 /// set.entry("poneyland").or_insert();
2404 ///
2405 /// match set.entry("poneyland") {
2406 /// Entry::Vacant(_) => panic!(),
2407 /// Entry::Occupied(entry) => assert_eq!(entry.get(), &"poneyland"),
2408 /// }
2409 /// ```
2410 #[cfg_attr(feature = "inline-more", inline)]
2411 pub fn get(&self) -> &T {
2412 self.inner.key()
2413 }
2414
2415 /// Takes the value out of the entry, and returns it.
2416 /// Keeps the allocated memory for reuse.
2417 ///
2418 /// # Examples
2419 ///
2420 /// ```
2421 /// use hashbrown::HashSet;
2422 /// use hashbrown::hash_set::Entry;
2423 ///
2424 /// let mut set: HashSet<&str> = HashSet::new();
2425 /// // The set is empty
2426 /// assert!(set.is_empty() && set.capacity() == 0);
2427 ///
2428 /// set.entry("poneyland").or_insert();
2429 /// let capacity_before_remove = set.capacity();
2430 ///
2431 /// if let Entry::Occupied(o) = set.entry("poneyland") {
2432 /// assert_eq!(o.remove(), "poneyland");
2433 /// }
2434 ///
2435 /// assert_eq!(set.contains("poneyland"), false);
2436 /// // Now set hold none elements but capacity is equal to the old one
2437 /// assert!(set.len() == 0 && set.capacity() == capacity_before_remove);
2438 /// ```
2439 #[cfg_attr(feature = "inline-more", inline)]
2440 pub fn remove(self) -> T {
2441 self.inner.remove_entry().0
2442 }
2443}
2444
2445impl<'a, T, S, A: Allocator> VacantEntry<'a, T, S, A> {
2446 /// Gets a reference to the value that would be used when inserting
2447 /// through the `VacantEntry`.
2448 ///
2449 /// # Examples
2450 ///
2451 /// ```
2452 /// use hashbrown::HashSet;
2453 ///
2454 /// let mut set: HashSet<&str> = HashSet::new();
2455 /// assert_eq!(set.entry("poneyland").get(), &"poneyland");
2456 /// ```
2457 #[cfg_attr(feature = "inline-more", inline)]
2458 pub fn get(&self) -> &T {
2459 self.inner.key()
2460 }
2461
2462 /// Take ownership of the value.
2463 ///
2464 /// # Examples
2465 ///
2466 /// ```
2467 /// use hashbrown::hash_set::{Entry, HashSet};
2468 ///
2469 /// let mut set: HashSet<&str> = HashSet::new();
2470 ///
2471 /// match set.entry("poneyland") {
2472 /// Entry::Occupied(_) => panic!(),
2473 /// Entry::Vacant(v) => assert_eq!(v.into_value(), "poneyland"),
2474 /// }
2475 /// ```
2476 #[cfg_attr(feature = "inline-more", inline)]
2477 pub fn into_value(self) -> T {
2478 self.inner.into_key()
2479 }
2480
2481 /// Sets the value of the entry with the `VacantEntry`'s value.
2482 ///
2483 /// # Examples
2484 ///
2485 /// ```
2486 /// use hashbrown::HashSet;
2487 /// use hashbrown::hash_set::Entry;
2488 ///
2489 /// let mut set: HashSet<&str> = HashSet::new();
2490 ///
2491 /// if let Entry::Vacant(o) = set.entry("poneyland") {
2492 /// o.insert();
2493 /// }
2494 /// assert!(set.contains("poneyland"));
2495 /// ```
2496 #[cfg_attr(feature = "inline-more", inline)]
2497 pub fn insert(self) -> OccupiedEntry<'a, T, S, A>
2498 where
2499 T: Hash,
2500 S: BuildHasher,
2501 {
2502 OccupiedEntry {
2503 inner: self.inner.insert_entry(()),
2504 }
2505 }
2506}
2507
2508#[expect(dead_code)]
2509fn assert_covariance() {
2510 fn set<'new>(v: HashSet<&'static str>) -> HashSet<&'new str> {
2511 v
2512 }
2513 fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> {
2514 v
2515 }
2516 fn into_iter<'new, A: Allocator>(v: IntoIter<&'static str, A>) -> IntoIter<&'new str, A> {
2517 v
2518 }
2519 fn difference<'a, 'new, A: Allocator>(
2520 v: Difference<'a, &'static str, DefaultHashBuilder, A>,
2521 ) -> Difference<'a, &'new str, DefaultHashBuilder, A> {
2522 v
2523 }
2524 fn symmetric_difference<'a, 'new, A: Allocator>(
2525 v: SymmetricDifference<'a, &'static str, DefaultHashBuilder, A>,
2526 ) -> SymmetricDifference<'a, &'new str, DefaultHashBuilder, A> {
2527 v
2528 }
2529 fn intersection<'a, 'new, A: Allocator>(
2530 v: Intersection<'a, &'static str, DefaultHashBuilder, A>,
2531 ) -> Intersection<'a, &'new str, DefaultHashBuilder, A> {
2532 v
2533 }
2534 fn union<'a, 'new, A: Allocator>(
2535 v: Union<'a, &'static str, DefaultHashBuilder, A>,
2536 ) -> Union<'a, &'new str, DefaultHashBuilder, A> {
2537 v
2538 }
2539 fn drain<'new, A: Allocator>(d: Drain<'static, &'static str, A>) -> Drain<'new, &'new str, A> {
2540 d
2541 }
2542}
2543
2544#[cfg(test)]
2545mod test_set {
2546 use super::{Equivalent, HashSet};
2547 use crate::DefaultHashBuilder;
2548 use crate::map::make_hash;
2549 use std::vec::Vec;
2550
2551 #[test]
2552 fn test_zero_capacities() {
2553 type HS = HashSet<i32>;
2554
2555 let s = HS::new();
2556 assert_eq!(s.capacity(), 0);
2557
2558 let s = HS::default();
2559 assert_eq!(s.capacity(), 0);
2560
2561 let s = HS::with_hasher(DefaultHashBuilder::default());
2562 assert_eq!(s.capacity(), 0);
2563
2564 let s = HS::with_capacity(0);
2565 assert_eq!(s.capacity(), 0);
2566
2567 let s = HS::with_capacity_and_hasher(0, DefaultHashBuilder::default());
2568 assert_eq!(s.capacity(), 0);
2569
2570 let mut s = HS::new();
2571 s.insert(1);
2572 s.insert(2);
2573 s.remove(&1);
2574 s.remove(&2);
2575 s.shrink_to_fit();
2576 assert_eq!(s.capacity(), 0);
2577
2578 let mut s = HS::new();
2579 s.reserve(0);
2580 assert_eq!(s.capacity(), 0);
2581 }
2582
2583 #[test]
2584 fn test_disjoint() {
2585 let mut xs = HashSet::new();
2586 let mut ys = HashSet::new();
2587 assert!(xs.is_disjoint(&ys));
2588 assert!(ys.is_disjoint(&xs));
2589 assert!(xs.insert(5));
2590 assert!(ys.insert(11));
2591 assert!(xs.is_disjoint(&ys));
2592 assert!(ys.is_disjoint(&xs));
2593 assert!(xs.insert(7));
2594 assert!(xs.insert(19));
2595 assert!(xs.insert(4));
2596 assert!(ys.insert(2));
2597 assert!(ys.insert(-11));
2598 assert!(xs.is_disjoint(&ys));
2599 assert!(ys.is_disjoint(&xs));
2600 assert!(ys.insert(7));
2601 assert!(!xs.is_disjoint(&ys));
2602 assert!(!ys.is_disjoint(&xs));
2603 }
2604
2605 #[test]
2606 fn test_subset_and_superset() {
2607 let mut a = HashSet::new();
2608 assert!(a.insert(0));
2609 assert!(a.insert(5));
2610 assert!(a.insert(11));
2611 assert!(a.insert(7));
2612
2613 let mut b = HashSet::new();
2614 assert!(b.insert(0));
2615 assert!(b.insert(7));
2616 assert!(b.insert(19));
2617 assert!(b.insert(250));
2618 assert!(b.insert(11));
2619 assert!(b.insert(200));
2620
2621 assert!(!a.is_subset(&b));
2622 assert!(!a.is_superset(&b));
2623 assert!(!b.is_subset(&a));
2624 assert!(!b.is_superset(&a));
2625
2626 assert!(b.insert(5));
2627
2628 assert!(a.is_subset(&b));
2629 assert!(!a.is_superset(&b));
2630 assert!(!b.is_subset(&a));
2631 assert!(b.is_superset(&a));
2632 }
2633
2634 #[test]
2635 fn test_iterate() {
2636 let mut a = HashSet::new();
2637 for i in 0..32 {
2638 assert!(a.insert(i));
2639 }
2640 let mut observed: u32 = 0;
2641 for k in &a {
2642 observed |= 1 << *k;
2643 }
2644 assert_eq!(observed, 0xFFFF_FFFF);
2645 }
2646
2647 #[test]
2648 fn test_intersection() {
2649 let mut a = HashSet::new();
2650 let mut b = HashSet::new();
2651
2652 assert!(a.insert(11));
2653 assert!(a.insert(1));
2654 assert!(a.insert(3));
2655 assert!(a.insert(77));
2656 assert!(a.insert(103));
2657 assert!(a.insert(5));
2658 assert!(a.insert(-5));
2659
2660 assert!(b.insert(2));
2661 assert!(b.insert(11));
2662 assert!(b.insert(77));
2663 assert!(b.insert(-9));
2664 assert!(b.insert(-42));
2665 assert!(b.insert(5));
2666 assert!(b.insert(3));
2667
2668 let mut i = 0;
2669 let expected = [3, 5, 11, 77];
2670 for x in a.intersection(&b) {
2671 assert!(expected.contains(x));
2672 i += 1;
2673 }
2674 assert_eq!(i, expected.len());
2675 }
2676
2677 #[test]
2678 fn test_difference() {
2679 let mut a = HashSet::new();
2680 let mut b = HashSet::new();
2681
2682 assert!(a.insert(1));
2683 assert!(a.insert(3));
2684 assert!(a.insert(5));
2685 assert!(a.insert(9));
2686 assert!(a.insert(11));
2687
2688 assert!(b.insert(3));
2689 assert!(b.insert(9));
2690
2691 let mut i = 0;
2692 let expected = [1, 5, 11];
2693 for x in a.difference(&b) {
2694 assert!(expected.contains(x));
2695 i += 1;
2696 }
2697 assert_eq!(i, expected.len());
2698 }
2699
2700 #[test]
2701 fn test_symmetric_difference() {
2702 let mut a = HashSet::new();
2703 let mut b = HashSet::new();
2704
2705 assert!(a.insert(1));
2706 assert!(a.insert(3));
2707 assert!(a.insert(5));
2708 assert!(a.insert(9));
2709 assert!(a.insert(11));
2710
2711 assert!(b.insert(-2));
2712 assert!(b.insert(3));
2713 assert!(b.insert(9));
2714 assert!(b.insert(14));
2715 assert!(b.insert(22));
2716
2717 let mut i = 0;
2718 let expected = [-2, 1, 5, 11, 14, 22];
2719 for x in a.symmetric_difference(&b) {
2720 assert!(expected.contains(x));
2721 i += 1;
2722 }
2723 assert_eq!(i, expected.len());
2724 }
2725
2726 #[test]
2727 fn test_sub_assign() {
2728 let mut a: HashSet<_> = vec![1, 2, 3, 4, 5].into_iter().collect();
2729 let b: HashSet<_> = vec![4, 5, 6].into_iter().collect();
2730
2731 a -= &b;
2732
2733 let mut i = 0;
2734 let expected = [1, 2, 3];
2735 for x in &a {
2736 assert!(expected.contains(x));
2737 i += 1;
2738 }
2739 assert_eq!(i, expected.len());
2740 }
2741
2742 #[test]
2743 fn test_union() {
2744 let mut a = HashSet::new();
2745 let mut b = HashSet::new();
2746
2747 assert!(a.insert(1));
2748 assert!(a.insert(3));
2749 assert!(a.insert(5));
2750 assert!(a.insert(9));
2751 assert!(a.insert(11));
2752 assert!(a.insert(16));
2753 assert!(a.insert(19));
2754 assert!(a.insert(24));
2755
2756 assert!(b.insert(-2));
2757 assert!(b.insert(1));
2758 assert!(b.insert(5));
2759 assert!(b.insert(9));
2760 assert!(b.insert(13));
2761 assert!(b.insert(19));
2762
2763 let mut i = 0;
2764 let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24];
2765 for x in a.union(&b) {
2766 assert!(expected.contains(x));
2767 i += 1;
2768 }
2769 assert_eq!(i, expected.len());
2770 }
2771
2772 #[test]
2773 fn test_from_map() {
2774 let mut a = crate::HashMap::new();
2775 a.insert(1, ());
2776 a.insert(2, ());
2777 a.insert(3, ());
2778 a.insert(4, ());
2779
2780 let a: HashSet<_> = a.into();
2781
2782 assert_eq!(a.len(), 4);
2783 assert!(a.contains(&1));
2784 assert!(a.contains(&2));
2785 assert!(a.contains(&3));
2786 assert!(a.contains(&4));
2787 }
2788
2789 #[test]
2790 fn test_from_iter() {
2791 let xs = [1, 2, 2, 3, 4, 5, 6, 7, 8, 9];
2792
2793 let set: HashSet<_> = xs.iter().copied().collect();
2794
2795 for x in &xs {
2796 assert!(set.contains(x));
2797 }
2798
2799 assert_eq!(set.iter().len(), xs.len() - 1);
2800 }
2801
2802 #[test]
2803 fn test_move_iter() {
2804 let hs = {
2805 let mut hs = HashSet::new();
2806
2807 hs.insert('a');
2808 hs.insert('b');
2809
2810 hs
2811 };
2812
2813 let v = hs.into_iter().collect::<Vec<char>>();
2814 assert!(v == ['a', 'b'] || v == ['b', 'a']);
2815 }
2816
2817 #[test]
2818 fn test_eq() {
2819 // These constants once happened to expose a bug in insert().
2820 // I'm keeping them around to prevent a regression.
2821 let mut s1 = HashSet::new();
2822
2823 s1.insert(1);
2824 s1.insert(2);
2825 s1.insert(3);
2826
2827 let mut s2 = HashSet::new();
2828
2829 s2.insert(1);
2830 s2.insert(2);
2831
2832 assert!(s1 != s2);
2833
2834 s2.insert(3);
2835
2836 assert_eq!(s1, s2);
2837 }
2838
2839 #[test]
2840 fn test_show() {
2841 let mut set = HashSet::new();
2842 let empty = HashSet::<i32>::new();
2843
2844 set.insert(1);
2845 set.insert(2);
2846
2847 let set_str = format!("{set:?}");
2848
2849 assert!(set_str == "{1, 2}" || set_str == "{2, 1}");
2850 assert_eq!(format!("{empty:?}"), "{}");
2851 }
2852
2853 #[test]
2854 fn test_trivial_drain() {
2855 let mut s = HashSet::<i32>::new();
2856 for _ in s.drain() {}
2857 assert!(s.is_empty());
2858 drop(s);
2859
2860 let mut s = HashSet::<i32>::new();
2861 drop(s.drain());
2862 assert!(s.is_empty());
2863 }
2864
2865 #[test]
2866 fn test_drain() {
2867 let mut s: HashSet<_> = (1..100).collect();
2868
2869 // try this a bunch of times to make sure we don't screw up internal state.
2870 for _ in 0..20 {
2871 assert_eq!(s.len(), 99);
2872
2873 {
2874 let mut last_i = 0;
2875 let mut d = s.drain();
2876 for (i, x) in d.by_ref().take(50).enumerate() {
2877 last_i = i;
2878 assert!(x != 0);
2879 }
2880 assert_eq!(last_i, 49);
2881 }
2882
2883 if !s.is_empty() {
2884 panic!("s should be empty!");
2885 }
2886
2887 // reset to try again.
2888 s.extend(1..100);
2889 }
2890 }
2891
2892 #[test]
2893 fn test_replace() {
2894 use core::hash;
2895
2896 #[derive(Debug)]
2897 #[expect(dead_code)]
2898 struct Foo(&'static str, i32);
2899
2900 impl PartialEq for Foo {
2901 fn eq(&self, other: &Self) -> bool {
2902 self.0 == other.0
2903 }
2904 }
2905
2906 impl Eq for Foo {}
2907
2908 impl hash::Hash for Foo {
2909 fn hash<H: hash::Hasher>(&self, h: &mut H) {
2910 self.0.hash(h);
2911 }
2912 }
2913
2914 let mut s = HashSet::new();
2915 assert_eq!(s.replace(Foo("a", 1)), None);
2916 assert_eq!(s.len(), 1);
2917 assert_eq!(s.replace(Foo("a", 2)), Some(Foo("a", 1)));
2918 assert_eq!(s.len(), 1);
2919
2920 let mut it = s.iter();
2921 assert_eq!(it.next(), Some(&Foo("a", 2)));
2922 assert_eq!(it.next(), None);
2923 }
2924
2925 #[test]
2926 fn test_extend_ref() {
2927 let mut a = HashSet::new();
2928 a.insert(1);
2929
2930 a.extend([2, 3, 4]);
2931
2932 assert_eq!(a.len(), 4);
2933 assert!(a.contains(&1));
2934 assert!(a.contains(&2));
2935 assert!(a.contains(&3));
2936 assert!(a.contains(&4));
2937
2938 let mut b = HashSet::new();
2939 b.insert(5);
2940 b.insert(6);
2941
2942 a.extend(&b);
2943
2944 assert_eq!(a.len(), 6);
2945 assert!(a.contains(&1));
2946 assert!(a.contains(&2));
2947 assert!(a.contains(&3));
2948 assert!(a.contains(&4));
2949 assert!(a.contains(&5));
2950 assert!(a.contains(&6));
2951 }
2952
2953 #[test]
2954 fn test_retain() {
2955 let xs = [1, 2, 3, 4, 5, 6];
2956 let mut set: HashSet<i32> = xs.iter().copied().collect();
2957 set.retain(|&k| k % 2 == 0);
2958 assert_eq!(set.len(), 3);
2959 assert!(set.contains(&2));
2960 assert!(set.contains(&4));
2961 assert!(set.contains(&6));
2962 }
2963
2964 #[test]
2965 fn test_extract_if() {
2966 {
2967 let mut set: HashSet<i32> = (0..8).collect();
2968 let drained = set.extract_if(|&k| k % 2 == 0);
2969 let mut out = drained.collect::<Vec<_>>();
2970 out.sort_unstable();
2971 assert_eq!(vec![0, 2, 4, 6], out);
2972 assert_eq!(set.len(), 4);
2973 }
2974 {
2975 let mut set: HashSet<i32> = (0..8).collect();
2976 set.extract_if(|&k| k % 2 == 0).for_each(drop);
2977 assert_eq!(set.len(), 4, "Removes non-matching items on drop");
2978 }
2979 }
2980
2981 #[test]
2982 fn test_const_with_hasher() {
2983 use core::hash::BuildHasher;
2984 use std::collections::hash_map::DefaultHasher;
2985
2986 #[derive(Clone)]
2987 struct MyHasher;
2988 impl BuildHasher for MyHasher {
2989 type Hasher = DefaultHasher;
2990
2991 fn build_hasher(&self) -> DefaultHasher {
2992 DefaultHasher::new()
2993 }
2994 }
2995
2996 const EMPTY_SET: HashSet<u32, MyHasher> = HashSet::with_hasher(MyHasher);
2997
2998 let mut set = EMPTY_SET;
2999 set.insert(19);
3000 assert!(set.contains(&19));
3001 }
3002
3003 #[test]
3004 fn rehash_in_place() {
3005 let mut set = HashSet::new();
3006
3007 for i in 0..224 {
3008 set.insert(i);
3009 }
3010
3011 assert_eq!(
3012 set.capacity(),
3013 224,
3014 "The set must be at or close to capacity to trigger a re hashing"
3015 );
3016
3017 for i in 100..1400 {
3018 set.remove(&(i - 100));
3019 set.insert(i);
3020 }
3021 }
3022
3023 #[test]
3024 fn collect() {
3025 // At the time of writing, this hits the ZST case in from_base_index
3026 // (and without the `map`, it does not).
3027 let mut _set: HashSet<_> = (0..3).map(|_| ()).collect();
3028 }
3029
3030 #[test]
3031 fn test_allocation_info() {
3032 assert_eq!(HashSet::<()>::new().allocation_size(), 0);
3033 assert_eq!(HashSet::<u32>::new().allocation_size(), 0);
3034 assert!(HashSet::<u32>::with_capacity(1).allocation_size() > core::mem::size_of::<u32>());
3035 }
3036
3037 #[test]
3038 fn duplicate_insert() {
3039 let mut set = HashSet::new();
3040 set.insert(1);
3041 set.get_or_insert_with(&1, |_| 1);
3042 set.get_or_insert_with(&1, |_| 1);
3043 assert!([1].iter().eq(set.iter()));
3044 }
3045
3046 #[test]
3047 #[should_panic]
3048 fn some_invalid_equivalent() {
3049 use core::hash::{Hash, Hasher};
3050 struct Invalid {
3051 count: u32,
3052 other: u32,
3053 }
3054
3055 struct InvalidRef {
3056 count: u32,
3057 other: u32,
3058 }
3059
3060 impl PartialEq for Invalid {
3061 fn eq(&self, other: &Self) -> bool {
3062 self.count == other.count && self.other == other.other
3063 }
3064 }
3065 impl Eq for Invalid {}
3066
3067 impl Equivalent<Invalid> for InvalidRef {
3068 fn equivalent(&self, key: &Invalid) -> bool {
3069 self.count == key.count && self.other == key.other
3070 }
3071 }
3072 impl Hash for Invalid {
3073 fn hash<H: Hasher>(&self, state: &mut H) {
3074 self.count.hash(state);
3075 }
3076 }
3077 impl Hash for InvalidRef {
3078 fn hash<H: Hasher>(&self, state: &mut H) {
3079 self.count.hash(state);
3080 }
3081 }
3082 let mut set: HashSet<Invalid> = HashSet::new();
3083 let key = InvalidRef { count: 1, other: 1 };
3084 let value = Invalid { count: 1, other: 2 };
3085 if make_hash(set.hasher(), &key) == make_hash(set.hasher(), &value) {
3086 set.get_or_insert_with(&key, |_| value);
3087 }
3088 }
3089}