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