std/collections/hash/set.rs
1#[cfg(test)]
2mod tests;
3
4use hashbrown::hash_set as base;
5
6use super::map::map_try_reserve_error;
7use crate::alloc::{Allocator, Global};
8use crate::borrow::Borrow;
9use crate::collections::TryReserveError;
10use crate::fmt;
11use crate::hash::{BuildHasher, Hash, RandomState};
12use crate::iter::{Chain, FusedIterator};
13use crate::ops::{BitAnd, BitOr, BitXor, Sub};
14
15/// A [hash set] implemented as a `HashMap` where the value is `()`.
16///
17/// As with the [`HashMap`] type, a `HashSet` requires that the elements
18/// implement the [`Eq`] and [`Hash`] traits. This can frequently be achieved by
19/// using `#[derive(PartialEq, Eq, Hash)]`. If you implement these yourself,
20/// it is important that the following property holds:
21///
22/// ```text
23/// k1 == k2 -> hash(k1) == hash(k2)
24/// ```
25///
26/// In other words, if two keys are equal, their hashes must be equal.
27/// Violating this property is a logic error.
28///
29/// It is also a logic error for a key to be modified in such a way that the key's
30/// hash, as determined by the [`Hash`] trait, or its equality, as determined by
31/// the [`Eq`] trait, changes while it is in the map. This is normally only
32/// possible through [`Cell`], [`RefCell`], global state, I/O, or unsafe code.
33///
34/// The behavior resulting from either logic error is not specified, but will
35/// be encapsulated to the `HashSet` that observed the logic error and not
36/// result in undefined behavior. This could include panics, incorrect results,
37/// aborts, memory leaks, and non-termination.
38///
39/// # Examples
40///
41/// ```
42/// use std::collections::HashSet;
43/// // Type inference lets us omit an explicit type signature (which
44/// // would be `HashSet<String>` in this example).
45/// let mut books = HashSet::new();
46///
47/// // Add some books.
48/// books.insert("A Dance With Dragons".to_string());
49/// books.insert("To Kill a Mockingbird".to_string());
50/// books.insert("The Odyssey".to_string());
51/// books.insert("The Great Gatsby".to_string());
52///
53/// // Check for a specific one.
54/// if !books.contains("The Winds of Winter") {
55/// println!("We have {} books, but The Winds of Winter ain't one.",
56/// books.len());
57/// }
58///
59/// // Remove a book.
60/// books.remove("The Odyssey");
61///
62/// // Iterate over everything.
63/// for book in &books {
64/// println!("{book}");
65/// }
66/// ```
67///
68/// The easiest way to use `HashSet` with a custom type is to derive
69/// [`Eq`] and [`Hash`]. We must also derive [`PartialEq`],
70/// which is required if [`Eq`] is derived.
71///
72/// ```
73/// use std::collections::HashSet;
74/// #[derive(Hash, Eq, PartialEq, Debug)]
75/// struct Viking {
76/// name: String,
77/// power: usize,
78/// }
79///
80/// let mut vikings = HashSet::new();
81///
82/// vikings.insert(Viking { name: "Einar".to_string(), power: 9 });
83/// vikings.insert(Viking { name: "Einar".to_string(), power: 9 });
84/// vikings.insert(Viking { name: "Olaf".to_string(), power: 4 });
85/// vikings.insert(Viking { name: "Harald".to_string(), power: 8 });
86///
87/// // Use derived implementation to print the vikings.
88/// for x in &vikings {
89/// println!("{x:?}");
90/// }
91/// ```
92///
93/// A `HashSet` with a known list of items can be initialized from an array:
94///
95/// ```
96/// use std::collections::HashSet;
97///
98/// let viking_names = HashSet::from(["Einar", "Olaf", "Harald"]);
99/// ```
100///
101/// [hash set]: crate::collections#use-the-set-variant-of-any-of-these-maps-when
102/// [`HashMap`]: crate::collections::HashMap
103/// [`RefCell`]: crate::cell::RefCell
104/// [`Cell`]: crate::cell::Cell
105///
106/// # Usage in `const` and `static`
107///
108/// Like `HashMap`, `HashSet` is randomly seeded: each `HashSet` instance uses a different seed,
109/// which means that `HashSet::new` cannot be used in const context. To construct a `HashSet` in the
110/// initializer of a `const` or `static` item, you will have to use a different hasher that does not
111/// involve a random seed, as demonstrated in the following example. **A `HashSet` constructed this
112/// way is not resistant against HashDoS!**
113///
114/// ```rust
115/// use std::collections::HashSet;
116/// use std::hash::{BuildHasherDefault, DefaultHasher};
117/// use std::sync::Mutex;
118///
119/// const EMPTY_SET: HashSet<String, BuildHasherDefault<DefaultHasher>> =
120/// HashSet::with_hasher(BuildHasherDefault::new());
121/// static SET: Mutex<HashSet<String, BuildHasherDefault<DefaultHasher>>> =
122/// Mutex::new(HashSet::with_hasher(BuildHasherDefault::new()));
123/// ```
124#[cfg_attr(not(test), rustc_diagnostic_item = "HashSet")]
125#[stable(feature = "rust1", since = "1.0.0")]
126pub struct HashSet<
127 T,
128 S = RandomState,
129 #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
130> {
131 base: base::HashSet<T, S, A>,
132}
133
134impl<T> HashSet<T, RandomState> {
135 /// Creates an empty `HashSet`.
136 ///
137 /// The hash set is initially created with a capacity of 0, so it will not allocate until it
138 /// is first inserted into.
139 ///
140 /// # Examples
141 ///
142 /// ```
143 /// use std::collections::HashSet;
144 /// let set: HashSet<i32> = HashSet::new();
145 /// ```
146 #[inline]
147 #[must_use]
148 #[stable(feature = "rust1", since = "1.0.0")]
149 pub fn new() -> HashSet<T, RandomState> {
150 Default::default()
151 }
152
153 /// Creates an empty `HashSet` with at least the specified capacity.
154 ///
155 /// The hash set will be able to hold at least `capacity` elements without
156 /// reallocating. This method is allowed to allocate for more elements than
157 /// `capacity`. If `capacity` is zero, the hash set will not allocate.
158 ///
159 /// # Examples
160 ///
161 /// ```
162 /// use std::collections::HashSet;
163 /// let set: HashSet<i32> = HashSet::with_capacity(10);
164 /// assert!(set.capacity() >= 10);
165 /// ```
166 #[inline]
167 #[must_use]
168 #[stable(feature = "rust1", since = "1.0.0")]
169 pub fn with_capacity(capacity: usize) -> HashSet<T, RandomState> {
170 HashSet::with_capacity_and_hasher(capacity, Default::default())
171 }
172}
173
174impl<T, A: Allocator> HashSet<T, RandomState, A> {
175 /// Creates an empty `HashSet` in the provided allocator.
176 ///
177 /// The hash set is initially created with a capacity of 0, so it will not allocate until it
178 /// is first inserted into.
179 /// # Examples
180 ///
181 /// ```
182 /// # #![feature(allocator_api)]
183 /// use std::alloc::Global;
184 /// use std::collections::HashSet;
185 ///
186 /// let set: HashSet<i32> = HashSet::new_in(Global);
187 /// ```
188 #[inline]
189 #[must_use]
190 #[unstable(feature = "allocator_api", issue = "32838")]
191 pub fn new_in(alloc: A) -> HashSet<T, RandomState, A> {
192 HashSet::with_hasher_in(Default::default(), alloc)
193 }
194
195 /// Creates an empty `HashSet` with at least the specified capacity.
196 ///
197 /// The hash set will be able to hold at least `capacity` elements without
198 /// reallocating. This method is allowed to allocate for more elements than
199 /// `capacity`. If `capacity` is zero, the hash set will not allocate.
200 ///
201 /// # Examples
202 ///
203 /// ```
204 /// # #![feature(allocator_api)]
205 /// use std::collections::HashSet;
206 /// use std::alloc::Global;
207 ///
208 /// let set: HashSet<i32> = HashSet::with_capacity_in(10, Global);
209 /// ```
210 #[inline]
211 #[must_use]
212 #[unstable(feature = "allocator_api", issue = "32838")]
213 pub fn with_capacity_in(capacity: usize, alloc: A) -> HashSet<T, RandomState, A> {
214 HashSet::with_capacity_and_hasher_in(capacity, Default::default(), alloc)
215 }
216}
217
218impl<T, S> HashSet<T, S> {
219 /// Creates a new empty hash set which will use the given hasher to hash
220 /// keys.
221 ///
222 /// The hash set is also created with the default initial capacity.
223 ///
224 /// Warning: `hasher` is normally randomly generated, and
225 /// is designed to allow `HashSet`s to be resistant to attacks that
226 /// cause many collisions and very poor performance. Setting it
227 /// manually using this function can expose a DoS attack vector.
228 ///
229 /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
230 /// the `HashSet` to be useful, see its documentation for details.
231 ///
232 /// # Examples
233 ///
234 /// ```
235 /// use std::collections::HashSet;
236 /// use std::hash::RandomState;
237 ///
238 /// let s = RandomState::new();
239 /// let mut set = HashSet::with_hasher(s);
240 /// set.insert(2);
241 /// ```
242 #[inline]
243 #[must_use]
244 #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
245 #[rustc_const_stable(feature = "const_collections_with_hasher", since = "1.85.0")]
246 pub const fn with_hasher(hasher: S) -> HashSet<T, S> {
247 HashSet { base: base::HashSet::with_hasher(hasher) }
248 }
249
250 /// Creates an empty `HashSet` with at least the specified capacity, using
251 /// `hasher` to hash the keys.
252 ///
253 /// The hash set will be able to hold at least `capacity` elements without
254 /// reallocating. This method is allowed to allocate for more elements than
255 /// `capacity`. If `capacity` is zero, the hash set will not allocate.
256 ///
257 /// Warning: `hasher` is normally randomly generated, and
258 /// is designed to allow `HashSet`s to be resistant to attacks that
259 /// cause many collisions and very poor performance. Setting it
260 /// manually using this function can expose a DoS attack vector.
261 ///
262 /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
263 /// the `HashSet` to be useful, see its documentation for details.
264 ///
265 /// # Examples
266 ///
267 /// ```
268 /// use std::collections::HashSet;
269 /// use std::hash::RandomState;
270 ///
271 /// let s = RandomState::new();
272 /// let mut set = HashSet::with_capacity_and_hasher(10, s);
273 /// set.insert(1);
274 /// ```
275 #[inline]
276 #[must_use]
277 #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
278 pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet<T, S> {
279 HashSet { base: base::HashSet::with_capacity_and_hasher(capacity, hasher) }
280 }
281}
282
283impl<T, S, A: Allocator> HashSet<T, S, A> {
284 /// Creates a new empty hash set which will use the given hasher to hash
285 /// keys and will allocate memory using the provided allocator.
286 ///
287 /// The hash set is also created with the default initial capacity.
288 ///
289 /// Warning: `hasher` is normally randomly generated, and
290 /// is designed to allow `HashSet`s to be resistant to attacks that
291 /// cause many collisions and very poor performance. Setting it
292 /// manually using this function can expose a DoS attack vector.
293 ///
294 /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
295 /// the `HashSet` to be useful, see its documentation for details.
296 ///
297 /// # Examples
298 ///
299 /// ```
300 /// # #![feature(allocator_api)]
301 /// use std::alloc::Global;
302 /// use std::collections::HashSet;
303 /// use std::hash::RandomState;
304 ///
305 /// let s = RandomState::new();
306 /// let set: HashSet<i32> = HashSet::with_hasher_in(s, Global);
307 /// ```
308 #[inline]
309 #[must_use]
310 #[unstable(feature = "allocator_api", issue = "32838")]
311 pub fn with_hasher_in(hasher: S, alloc: A) -> HashSet<T, S, A> {
312 HashSet { base: base::HashSet::with_hasher_in(hasher, alloc) }
313 }
314
315 /// Creates an empty `HashSet` with at least the specified capacity, using
316 /// `hasher` to hash the keys and `alloc` to allocate memory.
317 ///
318 /// The hash set will be able to hold at least `capacity` elements without
319 /// reallocating. This method is allowed to allocate for more elements than
320 /// `capacity`. If `capacity` is zero, the hash set will not allocate.
321 ///
322 /// Warning: `hasher` is normally randomly generated, and
323 /// is designed to allow `HashSet`s to be resistant to attacks that
324 /// cause many collisions and very poor performance. Setting it
325 /// manually using this function can expose a DoS attack vector.
326 ///
327 /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
328 /// the `HashSet` to be useful, see its documentation for details.
329 ///
330 /// # Examples
331 ///
332 /// ```
333 /// # #![feature(allocator_api)]
334 /// use std::alloc::Global;
335 /// use std::collections::HashSet;
336 /// use std::hash::RandomState;
337 ///
338 /// let s = RandomState::new();
339 /// let set: HashSet<i32> = HashSet::with_capacity_and_hasher_in(10, s, Global);
340 /// ```
341 #[inline]
342 #[must_use]
343 #[unstable(feature = "allocator_api", issue = "32838")]
344 pub fn with_capacity_and_hasher_in(capacity: usize, hasher: S, alloc: A) -> HashSet<T, S, A> {
345 HashSet { base: base::HashSet::with_capacity_and_hasher_in(capacity, hasher, alloc) }
346 }
347
348 /// Returns the number of elements the set can hold without reallocating.
349 ///
350 /// # Examples
351 ///
352 /// ```
353 /// use std::collections::HashSet;
354 /// let set: HashSet<i32> = HashSet::with_capacity(100);
355 /// assert!(set.capacity() >= 100);
356 /// ```
357 #[inline]
358 #[stable(feature = "rust1", since = "1.0.0")]
359 pub fn capacity(&self) -> usize {
360 self.base.capacity()
361 }
362
363 /// An iterator visiting all elements in arbitrary order.
364 /// The iterator element type is `&'a T`.
365 ///
366 /// # Examples
367 ///
368 /// ```
369 /// use std::collections::HashSet;
370 /// let mut set = HashSet::new();
371 /// set.insert("a");
372 /// set.insert("b");
373 ///
374 /// // Will print in an arbitrary order.
375 /// for x in set.iter() {
376 /// println!("{x}");
377 /// }
378 /// ```
379 ///
380 /// # Performance
381 ///
382 /// In the current implementation, iterating over set takes O(capacity) time
383 /// instead of O(len) because it internally visits empty buckets too.
384 #[inline]
385 #[rustc_lint_query_instability]
386 #[stable(feature = "rust1", since = "1.0.0")]
387 #[cfg_attr(not(test), rustc_diagnostic_item = "hashset_iter")]
388 pub fn iter(&self) -> Iter<'_, T> {
389 Iter { base: self.base.iter() }
390 }
391
392 /// Returns the number of elements in the set.
393 ///
394 /// # Examples
395 ///
396 /// ```
397 /// use std::collections::HashSet;
398 ///
399 /// let mut v = HashSet::new();
400 /// assert_eq!(v.len(), 0);
401 /// v.insert(1);
402 /// assert_eq!(v.len(), 1);
403 /// ```
404 #[inline]
405 #[stable(feature = "rust1", since = "1.0.0")]
406 pub fn len(&self) -> usize {
407 self.base.len()
408 }
409
410 /// Returns `true` if the set contains no elements.
411 ///
412 /// # Examples
413 ///
414 /// ```
415 /// use std::collections::HashSet;
416 ///
417 /// let mut v = HashSet::new();
418 /// assert!(v.is_empty());
419 /// v.insert(1);
420 /// assert!(!v.is_empty());
421 /// ```
422 #[inline]
423 #[stable(feature = "rust1", since = "1.0.0")]
424 pub fn is_empty(&self) -> bool {
425 self.base.is_empty()
426 }
427
428 /// Clears the set, returning all elements as an iterator. Keeps the
429 /// allocated memory for reuse.
430 ///
431 /// If the returned iterator is dropped before being fully consumed, it
432 /// drops the remaining elements. The returned iterator keeps a mutable
433 /// borrow on the set to optimize its implementation.
434 ///
435 /// # Examples
436 ///
437 /// ```
438 /// use std::collections::HashSet;
439 ///
440 /// let mut set = HashSet::from([1, 2, 3]);
441 /// assert!(!set.is_empty());
442 ///
443 /// // print 1, 2, 3 in an arbitrary order
444 /// for i in set.drain() {
445 /// println!("{i}");
446 /// }
447 ///
448 /// assert!(set.is_empty());
449 /// ```
450 #[inline]
451 #[rustc_lint_query_instability]
452 #[stable(feature = "drain", since = "1.6.0")]
453 pub fn drain(&mut self) -> Drain<'_, T, A> {
454 Drain { base: self.base.drain() }
455 }
456
457 /// Creates an iterator which uses a closure to determine if an element should be removed.
458 ///
459 /// If the closure returns `true`, the element is removed from the set and
460 /// yielded. If the closure returns `false`, or panics, the element remains
461 /// in the set and will not be yielded.
462 ///
463 /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
464 /// or the iteration short-circuits, then the remaining elements will be retained.
465 /// Use [`retain`] with a negated predicate if you do not need the returned iterator.
466 ///
467 /// [`retain`]: HashSet::retain
468 ///
469 /// # Examples
470 ///
471 /// Splitting a set into even and odd values, reusing the original set:
472 ///
473 /// ```
474 /// use std::collections::HashSet;
475 ///
476 /// let mut set: HashSet<i32> = (0..8).collect();
477 /// let extracted: HashSet<i32> = set.extract_if(|v| v % 2 == 0).collect();
478 ///
479 /// let mut evens = extracted.into_iter().collect::<Vec<_>>();
480 /// let mut odds = set.into_iter().collect::<Vec<_>>();
481 /// evens.sort();
482 /// odds.sort();
483 ///
484 /// assert_eq!(evens, vec![0, 2, 4, 6]);
485 /// assert_eq!(odds, vec![1, 3, 5, 7]);
486 /// ```
487 #[inline]
488 #[rustc_lint_query_instability]
489 #[stable(feature = "hash_extract_if", since = "1.88.0")]
490 pub fn extract_if<F>(&mut self, pred: F) -> ExtractIf<'_, T, F, A>
491 where
492 F: FnMut(&T) -> bool,
493 {
494 ExtractIf { base: self.base.extract_if(pred) }
495 }
496
497 /// Retains only the elements specified by the predicate.
498 ///
499 /// In other words, remove all elements `e` for which `f(&e)` returns `false`.
500 /// The elements are visited in unsorted (and unspecified) order.
501 ///
502 /// # Examples
503 ///
504 /// ```
505 /// use std::collections::HashSet;
506 ///
507 /// let mut set = HashSet::from([1, 2, 3, 4, 5, 6]);
508 /// set.retain(|&k| k % 2 == 0);
509 /// assert_eq!(set, HashSet::from([2, 4, 6]));
510 /// ```
511 ///
512 /// # Performance
513 ///
514 /// In the current implementation, this operation takes O(capacity) time
515 /// instead of O(len) because it internally visits empty buckets too.
516 #[rustc_lint_query_instability]
517 #[stable(feature = "retain_hash_collection", since = "1.18.0")]
518 pub fn retain<F>(&mut self, f: F)
519 where
520 F: FnMut(&T) -> bool,
521 {
522 self.base.retain(f)
523 }
524
525 /// Clears the set, removing all values.
526 ///
527 /// # Examples
528 ///
529 /// ```
530 /// use std::collections::HashSet;
531 ///
532 /// let mut v = HashSet::new();
533 /// v.insert(1);
534 /// v.clear();
535 /// assert!(v.is_empty());
536 /// ```
537 #[inline]
538 #[stable(feature = "rust1", since = "1.0.0")]
539 pub fn clear(&mut self) {
540 self.base.clear()
541 }
542
543 /// Returns a reference to the set's [`BuildHasher`].
544 ///
545 /// # Examples
546 ///
547 /// ```
548 /// use std::collections::HashSet;
549 /// use std::hash::RandomState;
550 ///
551 /// let hasher = RandomState::new();
552 /// let set: HashSet<i32> = HashSet::with_hasher(hasher);
553 /// let hasher: &RandomState = set.hasher();
554 /// ```
555 #[inline]
556 #[stable(feature = "hashmap_public_hasher", since = "1.9.0")]
557 pub fn hasher(&self) -> &S {
558 self.base.hasher()
559 }
560}
561
562impl<T, S, A> HashSet<T, S, A>
563where
564 T: Eq + Hash,
565 S: BuildHasher,
566 A: Allocator,
567{
568 /// Reserves capacity for at least `additional` more elements to be inserted
569 /// in the `HashSet`. The collection may reserve more space to speculatively
570 /// avoid frequent reallocations. After calling `reserve`,
571 /// capacity will be greater than or equal to `self.len() + additional`.
572 /// Does nothing if capacity is already sufficient.
573 ///
574 /// # Panics
575 ///
576 /// Panics if the new allocation size overflows `usize`.
577 ///
578 /// # Examples
579 ///
580 /// ```
581 /// use std::collections::HashSet;
582 /// let mut set: HashSet<i32> = HashSet::new();
583 /// set.reserve(10);
584 /// assert!(set.capacity() >= 10);
585 /// ```
586 #[inline]
587 #[stable(feature = "rust1", since = "1.0.0")]
588 pub fn reserve(&mut self, additional: usize) {
589 self.base.reserve(additional)
590 }
591
592 /// Tries to reserve capacity for at least `additional` more elements to be inserted
593 /// in the `HashSet`. The collection may reserve more space to speculatively
594 /// avoid frequent reallocations. After calling `try_reserve`,
595 /// capacity will be greater than or equal to `self.len() + additional` if
596 /// it returns `Ok(())`.
597 /// Does nothing if capacity is already sufficient.
598 ///
599 /// # Errors
600 ///
601 /// If the capacity overflows, or the allocator reports a failure, then an error
602 /// is returned.
603 ///
604 /// # Examples
605 ///
606 /// ```
607 /// use std::collections::HashSet;
608 /// let mut set: HashSet<i32> = HashSet::new();
609 /// set.try_reserve(10).expect("why is the test harness OOMing on a handful of bytes?");
610 /// ```
611 #[inline]
612 #[stable(feature = "try_reserve", since = "1.57.0")]
613 pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
614 self.base.try_reserve(additional).map_err(map_try_reserve_error)
615 }
616
617 /// Shrinks the capacity of the set as much as possible. It will drop
618 /// down as much as possible while maintaining the internal rules
619 /// and possibly leaving some space in accordance with the resize policy.
620 ///
621 /// # Examples
622 ///
623 /// ```
624 /// use std::collections::HashSet;
625 ///
626 /// let mut set = HashSet::with_capacity(100);
627 /// set.insert(1);
628 /// set.insert(2);
629 /// assert!(set.capacity() >= 100);
630 /// set.shrink_to_fit();
631 /// assert!(set.capacity() >= 2);
632 /// ```
633 #[inline]
634 #[stable(feature = "rust1", since = "1.0.0")]
635 pub fn shrink_to_fit(&mut self) {
636 self.base.shrink_to_fit()
637 }
638
639 /// Shrinks the capacity of the set with a lower limit. It will drop
640 /// down no lower than the supplied limit while maintaining the internal rules
641 /// and possibly leaving some space in accordance with the resize policy.
642 ///
643 /// If the current capacity is less than the lower limit, this is a no-op.
644 /// # Examples
645 ///
646 /// ```
647 /// use std::collections::HashSet;
648 ///
649 /// let mut set = HashSet::with_capacity(100);
650 /// set.insert(1);
651 /// set.insert(2);
652 /// assert!(set.capacity() >= 100);
653 /// set.shrink_to(10);
654 /// assert!(set.capacity() >= 10);
655 /// set.shrink_to(0);
656 /// assert!(set.capacity() >= 2);
657 /// ```
658 #[inline]
659 #[stable(feature = "shrink_to", since = "1.56.0")]
660 pub fn shrink_to(&mut self, min_capacity: usize) {
661 self.base.shrink_to(min_capacity)
662 }
663
664 /// Visits the values representing the difference,
665 /// i.e., the values that are in `self` but not in `other`.
666 ///
667 /// # Examples
668 ///
669 /// ```
670 /// use std::collections::HashSet;
671 /// let a = HashSet::from([1, 2, 3]);
672 /// let b = HashSet::from([4, 2, 3, 4]);
673 ///
674 /// // Can be seen as `a - b`.
675 /// for x in a.difference(&b) {
676 /// println!("{x}"); // Print 1
677 /// }
678 ///
679 /// let diff: HashSet<_> = a.difference(&b).collect();
680 /// assert_eq!(diff, [1].iter().collect());
681 ///
682 /// // Note that difference is not symmetric,
683 /// // and `b - a` means something else:
684 /// let diff: HashSet<_> = b.difference(&a).collect();
685 /// assert_eq!(diff, [4].iter().collect());
686 /// ```
687 #[inline]
688 #[rustc_lint_query_instability]
689 #[stable(feature = "rust1", since = "1.0.0")]
690 pub fn difference<'a>(&'a self, other: &'a HashSet<T, S, A>) -> Difference<'a, T, S, A> {
691 Difference { iter: self.iter(), other }
692 }
693
694 /// Visits the values representing the symmetric difference,
695 /// i.e., the values that are in `self` or in `other` but not in both.
696 ///
697 /// # Examples
698 ///
699 /// ```
700 /// use std::collections::HashSet;
701 /// let a = HashSet::from([1, 2, 3]);
702 /// let b = HashSet::from([4, 2, 3, 4]);
703 ///
704 /// // Print 1, 4 in arbitrary order.
705 /// for x in a.symmetric_difference(&b) {
706 /// println!("{x}");
707 /// }
708 ///
709 /// let diff1: HashSet<_> = a.symmetric_difference(&b).collect();
710 /// let diff2: HashSet<_> = b.symmetric_difference(&a).collect();
711 ///
712 /// assert_eq!(diff1, diff2);
713 /// assert_eq!(diff1, [1, 4].iter().collect());
714 /// ```
715 #[inline]
716 #[rustc_lint_query_instability]
717 #[stable(feature = "rust1", since = "1.0.0")]
718 pub fn symmetric_difference<'a>(
719 &'a self,
720 other: &'a HashSet<T, S, A>,
721 ) -> SymmetricDifference<'a, T, S, A> {
722 SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) }
723 }
724
725 /// Visits the values representing the intersection,
726 /// i.e., the values that are both in `self` and `other`.
727 ///
728 /// When an equal element is present in `self` and `other`
729 /// then the resulting `Intersection` may yield references to
730 /// one or the other. This can be relevant if `T` contains fields which
731 /// are not compared by its `Eq` implementation, and may hold different
732 /// value between the two equal copies of `T` in the two sets.
733 ///
734 /// # Examples
735 ///
736 /// ```
737 /// use std::collections::HashSet;
738 /// let a = HashSet::from([1, 2, 3]);
739 /// let b = HashSet::from([4, 2, 3, 4]);
740 ///
741 /// // Print 2, 3 in arbitrary order.
742 /// for x in a.intersection(&b) {
743 /// println!("{x}");
744 /// }
745 ///
746 /// let intersection: HashSet<_> = a.intersection(&b).collect();
747 /// assert_eq!(intersection, [2, 3].iter().collect());
748 /// ```
749 #[inline]
750 #[rustc_lint_query_instability]
751 #[stable(feature = "rust1", since = "1.0.0")]
752 pub fn intersection<'a>(&'a self, other: &'a HashSet<T, S, A>) -> Intersection<'a, T, S, A> {
753 if self.len() <= other.len() {
754 Intersection { iter: self.iter(), other }
755 } else {
756 Intersection { iter: other.iter(), other: self }
757 }
758 }
759
760 /// Visits the values representing the union,
761 /// i.e., all the values in `self` or `other`, without duplicates.
762 ///
763 /// # Examples
764 ///
765 /// ```
766 /// use std::collections::HashSet;
767 /// let a = HashSet::from([1, 2, 3]);
768 /// let b = HashSet::from([4, 2, 3, 4]);
769 ///
770 /// // Print 1, 2, 3, 4 in arbitrary order.
771 /// for x in a.union(&b) {
772 /// println!("{x}");
773 /// }
774 ///
775 /// let union: HashSet<_> = a.union(&b).collect();
776 /// assert_eq!(union, [1, 2, 3, 4].iter().collect());
777 /// ```
778 #[inline]
779 #[rustc_lint_query_instability]
780 #[stable(feature = "rust1", since = "1.0.0")]
781 pub fn union<'a>(&'a self, other: &'a HashSet<T, S, A>) -> Union<'a, T, S, A> {
782 if self.len() >= other.len() {
783 Union { iter: self.iter().chain(other.difference(self)) }
784 } else {
785 Union { iter: other.iter().chain(self.difference(other)) }
786 }
787 }
788
789 /// Returns `true` if the set contains a value.
790 ///
791 /// The value may be any borrowed form of the set's value type, but
792 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
793 /// the value type.
794 ///
795 /// # Examples
796 ///
797 /// ```
798 /// use std::collections::HashSet;
799 ///
800 /// let set = HashSet::from([1, 2, 3]);
801 /// assert_eq!(set.contains(&1), true);
802 /// assert_eq!(set.contains(&4), false);
803 /// ```
804 #[inline]
805 #[stable(feature = "rust1", since = "1.0.0")]
806 pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
807 where
808 T: Borrow<Q>,
809 Q: Hash + Eq,
810 {
811 self.base.contains(value)
812 }
813
814 /// Returns a reference to the value in the set, if any, that is equal to the given value.
815 ///
816 /// The value may be any borrowed form of the set's value type, but
817 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
818 /// the value type.
819 ///
820 /// # Examples
821 ///
822 /// ```
823 /// use std::collections::HashSet;
824 ///
825 /// let set = HashSet::from([1, 2, 3]);
826 /// assert_eq!(set.get(&2), Some(&2));
827 /// assert_eq!(set.get(&4), None);
828 /// ```
829 #[inline]
830 #[stable(feature = "set_recovery", since = "1.9.0")]
831 pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T>
832 where
833 T: Borrow<Q>,
834 Q: Hash + Eq,
835 {
836 self.base.get(value)
837 }
838
839 /// Inserts the given `value` into the set if it is not present, then
840 /// returns a reference to the value in the set.
841 ///
842 /// # Examples
843 ///
844 /// ```
845 /// #![feature(hash_set_entry)]
846 ///
847 /// use std::collections::HashSet;
848 ///
849 /// let mut set = HashSet::from([1, 2, 3]);
850 /// assert_eq!(set.len(), 3);
851 /// assert_eq!(set.get_or_insert(2), &2);
852 /// assert_eq!(set.get_or_insert(100), &100);
853 /// assert_eq!(set.len(), 4); // 100 was inserted
854 /// ```
855 #[inline]
856 #[unstable(feature = "hash_set_entry", issue = "60896")]
857 pub fn get_or_insert(&mut self, value: T) -> &T {
858 // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with
859 // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`.
860 self.base.get_or_insert(value)
861 }
862
863 /// Inserts a value computed from `f` into the set if the given `value` is
864 /// not present, then returns a reference to the value in the set.
865 ///
866 /// # Examples
867 ///
868 /// ```
869 /// #![feature(hash_set_entry)]
870 ///
871 /// use std::collections::HashSet;
872 ///
873 /// let mut set: HashSet<String> = ["cat", "dog", "horse"]
874 /// .iter().map(|&pet| pet.to_owned()).collect();
875 ///
876 /// assert_eq!(set.len(), 3);
877 /// for &pet in &["cat", "dog", "fish"] {
878 /// let value = set.get_or_insert_with(pet, str::to_owned);
879 /// assert_eq!(value, pet);
880 /// }
881 /// assert_eq!(set.len(), 4); // a new "fish" was inserted
882 /// ```
883 #[inline]
884 #[unstable(feature = "hash_set_entry", issue = "60896")]
885 pub fn get_or_insert_with<Q: ?Sized, F>(&mut self, value: &Q, f: F) -> &T
886 where
887 T: Borrow<Q>,
888 Q: Hash + Eq,
889 F: FnOnce(&Q) -> T,
890 {
891 // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with
892 // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`.
893 self.base.get_or_insert_with(value, f)
894 }
895
896 /// Gets the given value's corresponding entry in the set for in-place manipulation.
897 ///
898 /// # Examples
899 ///
900 /// ```
901 /// #![feature(hash_set_entry)]
902 ///
903 /// use std::collections::HashSet;
904 /// use std::collections::hash_set::Entry::*;
905 ///
906 /// let mut singles = HashSet::new();
907 /// let mut dupes = HashSet::new();
908 ///
909 /// for ch in "a short treatise on fungi".chars() {
910 /// if let Vacant(dupe_entry) = dupes.entry(ch) {
911 /// // We haven't already seen a duplicate, so
912 /// // check if we've at least seen it once.
913 /// match singles.entry(ch) {
914 /// Vacant(single_entry) => {
915 /// // We found a new character for the first time.
916 /// single_entry.insert()
917 /// }
918 /// Occupied(single_entry) => {
919 /// // We've already seen this once, "move" it to dupes.
920 /// single_entry.remove();
921 /// dupe_entry.insert();
922 /// }
923 /// }
924 /// }
925 /// }
926 ///
927 /// assert!(!singles.contains(&'t') && dupes.contains(&'t'));
928 /// assert!(singles.contains(&'u') && !dupes.contains(&'u'));
929 /// assert!(!singles.contains(&'v') && !dupes.contains(&'v'));
930 /// ```
931 #[inline]
932 #[unstable(feature = "hash_set_entry", issue = "60896")]
933 pub fn entry(&mut self, value: T) -> Entry<'_, T, S, A> {
934 map_entry(self.base.entry(value))
935 }
936
937 /// Returns `true` if `self` has no elements in common with `other`.
938 /// This is equivalent to checking for an empty intersection.
939 ///
940 /// # Examples
941 ///
942 /// ```
943 /// use std::collections::HashSet;
944 ///
945 /// let a = HashSet::from([1, 2, 3]);
946 /// let mut b = HashSet::new();
947 ///
948 /// assert_eq!(a.is_disjoint(&b), true);
949 /// b.insert(4);
950 /// assert_eq!(a.is_disjoint(&b), true);
951 /// b.insert(1);
952 /// assert_eq!(a.is_disjoint(&b), false);
953 /// ```
954 #[stable(feature = "rust1", since = "1.0.0")]
955 pub fn is_disjoint(&self, other: &HashSet<T, S, A>) -> bool {
956 if self.len() <= other.len() {
957 self.iter().all(|v| !other.contains(v))
958 } else {
959 other.iter().all(|v| !self.contains(v))
960 }
961 }
962
963 /// Returns `true` if the set is a subset of another,
964 /// i.e., `other` contains at least all the values in `self`.
965 ///
966 /// # Examples
967 ///
968 /// ```
969 /// use std::collections::HashSet;
970 ///
971 /// let sup = HashSet::from([1, 2, 3]);
972 /// let mut set = HashSet::new();
973 ///
974 /// assert_eq!(set.is_subset(&sup), true);
975 /// set.insert(2);
976 /// assert_eq!(set.is_subset(&sup), true);
977 /// set.insert(4);
978 /// assert_eq!(set.is_subset(&sup), false);
979 /// ```
980 #[stable(feature = "rust1", since = "1.0.0")]
981 pub fn is_subset(&self, other: &HashSet<T, S, A>) -> bool {
982 if self.len() <= other.len() { self.iter().all(|v| other.contains(v)) } else { false }
983 }
984
985 /// Returns `true` if the set is a superset of another,
986 /// i.e., `self` contains at least all the values in `other`.
987 ///
988 /// # Examples
989 ///
990 /// ```
991 /// use std::collections::HashSet;
992 ///
993 /// let sub = HashSet::from([1, 2]);
994 /// let mut set = HashSet::new();
995 ///
996 /// assert_eq!(set.is_superset(&sub), false);
997 ///
998 /// set.insert(0);
999 /// set.insert(1);
1000 /// assert_eq!(set.is_superset(&sub), false);
1001 ///
1002 /// set.insert(2);
1003 /// assert_eq!(set.is_superset(&sub), true);
1004 /// ```
1005 #[inline]
1006 #[stable(feature = "rust1", since = "1.0.0")]
1007 pub fn is_superset(&self, other: &HashSet<T, S, A>) -> bool {
1008 other.is_subset(self)
1009 }
1010
1011 /// Adds a value to the set.
1012 ///
1013 /// Returns whether the value was newly inserted. That is:
1014 ///
1015 /// - If the set did not previously contain this value, `true` is returned.
1016 /// - If the set already contained this value, `false` is returned,
1017 /// and the set is not modified: original value is not replaced,
1018 /// and the value passed as argument is dropped.
1019 ///
1020 /// # Examples
1021 ///
1022 /// ```
1023 /// use std::collections::HashSet;
1024 ///
1025 /// let mut set = HashSet::new();
1026 ///
1027 /// assert_eq!(set.insert(2), true);
1028 /// assert_eq!(set.insert(2), false);
1029 /// assert_eq!(set.len(), 1);
1030 /// ```
1031 #[inline]
1032 #[stable(feature = "rust1", since = "1.0.0")]
1033 #[rustc_confusables("push", "append", "put")]
1034 pub fn insert(&mut self, value: T) -> bool {
1035 self.base.insert(value)
1036 }
1037
1038 /// Adds a value to the set, replacing the existing value, if any, that is equal to the given
1039 /// one. Returns the replaced value.
1040 ///
1041 /// # Examples
1042 ///
1043 /// ```
1044 /// use std::collections::HashSet;
1045 ///
1046 /// let mut set = HashSet::new();
1047 /// set.insert(Vec::<i32>::new());
1048 ///
1049 /// assert_eq!(set.get(&[][..]).unwrap().capacity(), 0);
1050 /// set.replace(Vec::with_capacity(10));
1051 /// assert_eq!(set.get(&[][..]).unwrap().capacity(), 10);
1052 /// ```
1053 #[inline]
1054 #[stable(feature = "set_recovery", since = "1.9.0")]
1055 #[rustc_confusables("swap")]
1056 pub fn replace(&mut self, value: T) -> Option<T> {
1057 self.base.replace(value)
1058 }
1059
1060 /// Removes a value from the set. Returns whether the value was
1061 /// present in the set.
1062 ///
1063 /// The value may be any borrowed form of the set's value type, but
1064 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1065 /// the value type.
1066 ///
1067 /// # Examples
1068 ///
1069 /// ```
1070 /// use std::collections::HashSet;
1071 ///
1072 /// let mut set = HashSet::new();
1073 ///
1074 /// set.insert(2);
1075 /// assert_eq!(set.remove(&2), true);
1076 /// assert_eq!(set.remove(&2), false);
1077 /// ```
1078 #[inline]
1079 #[stable(feature = "rust1", since = "1.0.0")]
1080 #[rustc_confusables("delete", "take")]
1081 pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
1082 where
1083 T: Borrow<Q>,
1084 Q: Hash + Eq,
1085 {
1086 self.base.remove(value)
1087 }
1088
1089 /// Removes and returns the value in the set, if any, that is equal to the given one.
1090 ///
1091 /// The value may be any borrowed form of the set's value type, but
1092 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1093 /// the value type.
1094 ///
1095 /// # Examples
1096 ///
1097 /// ```
1098 /// use std::collections::HashSet;
1099 ///
1100 /// let mut set = HashSet::from([1, 2, 3]);
1101 /// assert_eq!(set.take(&2), Some(2));
1102 /// assert_eq!(set.take(&2), None);
1103 /// ```
1104 #[inline]
1105 #[stable(feature = "set_recovery", since = "1.9.0")]
1106 pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T>
1107 where
1108 T: Borrow<Q>,
1109 Q: Hash + Eq,
1110 {
1111 self.base.take(value)
1112 }
1113}
1114
1115#[inline]
1116fn map_entry<'a, K: 'a, V: 'a, A: Allocator>(raw: base::Entry<'a, K, V, A>) -> Entry<'a, K, V, A> {
1117 match raw {
1118 base::Entry::Occupied(base) => Entry::Occupied(OccupiedEntry { base }),
1119 base::Entry::Vacant(base) => Entry::Vacant(VacantEntry { base }),
1120 }
1121}
1122
1123#[stable(feature = "rust1", since = "1.0.0")]
1124impl<T, S, A> Clone for HashSet<T, S, A>
1125where
1126 T: Clone,
1127 S: Clone,
1128 A: Allocator + Clone,
1129{
1130 #[inline]
1131 fn clone(&self) -> Self {
1132 Self { base: self.base.clone() }
1133 }
1134
1135 /// Overwrites the contents of `self` with a clone of the contents of `source`.
1136 ///
1137 /// This method is preferred over simply assigning `source.clone()` to `self`,
1138 /// as it avoids reallocation if possible.
1139 #[inline]
1140 fn clone_from(&mut self, other: &Self) {
1141 self.base.clone_from(&other.base);
1142 }
1143}
1144
1145#[stable(feature = "rust1", since = "1.0.0")]
1146impl<T, S, A> PartialEq for HashSet<T, S, A>
1147where
1148 T: Eq + Hash,
1149 S: BuildHasher,
1150 A: Allocator,
1151{
1152 fn eq(&self, other: &HashSet<T, S, A>) -> bool {
1153 if self.len() != other.len() {
1154 return false;
1155 }
1156
1157 self.iter().all(|key| other.contains(key))
1158 }
1159}
1160
1161#[stable(feature = "rust1", since = "1.0.0")]
1162impl<T, S, A> Eq for HashSet<T, S, A>
1163where
1164 T: Eq + Hash,
1165 S: BuildHasher,
1166 A: Allocator,
1167{
1168}
1169
1170#[stable(feature = "rust1", since = "1.0.0")]
1171impl<T, S, A> fmt::Debug for HashSet<T, S, A>
1172where
1173 T: fmt::Debug,
1174 A: Allocator,
1175{
1176 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1177 f.debug_set().entries(self.iter()).finish()
1178 }
1179}
1180
1181#[stable(feature = "rust1", since = "1.0.0")]
1182impl<T, S> FromIterator<T> for HashSet<T, S>
1183where
1184 T: Eq + Hash,
1185 S: BuildHasher + Default,
1186{
1187 #[inline]
1188 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> HashSet<T, S> {
1189 let mut set = HashSet::with_hasher(Default::default());
1190 set.extend(iter);
1191 set
1192 }
1193}
1194
1195#[stable(feature = "std_collections_from_array", since = "1.56.0")]
1196// Note: as what is currently the most convenient built-in way to construct
1197// a HashSet, a simple usage of this function must not *require* the user
1198// to provide a type annotation in order to infer the third type parameter
1199// (the hasher parameter, conventionally "S").
1200// To that end, this impl is defined using RandomState as the concrete
1201// type of S, rather than being generic over `S: BuildHasher + Default`.
1202// It is expected that users who want to specify a hasher will manually use
1203// `with_capacity_and_hasher`.
1204// If type parameter defaults worked on impls, and if type parameter
1205// defaults could be mixed with const generics, then perhaps
1206// this could be generalized.
1207// See also the equivalent impl on HashMap.
1208impl<T, const N: usize> From<[T; N]> for HashSet<T, RandomState>
1209where
1210 T: Eq + Hash,
1211{
1212 /// Converts a `[T; N]` into a `HashSet<T>`.
1213 ///
1214 /// If the array contains any equal values,
1215 /// all but one will be dropped.
1216 ///
1217 /// # Examples
1218 ///
1219 /// ```
1220 /// use std::collections::HashSet;
1221 ///
1222 /// let set1 = HashSet::from([1, 2, 3, 4]);
1223 /// let set2: HashSet<_> = [1, 2, 3, 4].into();
1224 /// assert_eq!(set1, set2);
1225 /// ```
1226 fn from(arr: [T; N]) -> Self {
1227 Self::from_iter(arr)
1228 }
1229}
1230
1231#[stable(feature = "rust1", since = "1.0.0")]
1232impl<T, S, A> Extend<T> for HashSet<T, S, A>
1233where
1234 T: Eq + Hash,
1235 S: BuildHasher,
1236 A: Allocator,
1237{
1238 #[inline]
1239 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
1240 self.base.extend(iter);
1241 }
1242
1243 #[inline]
1244 fn extend_one(&mut self, item: T) {
1245 self.base.insert(item);
1246 }
1247
1248 #[inline]
1249 fn extend_reserve(&mut self, additional: usize) {
1250 self.base.extend_reserve(additional);
1251 }
1252}
1253
1254#[stable(feature = "hash_extend_copy", since = "1.4.0")]
1255impl<'a, T, S, A> Extend<&'a T> for HashSet<T, S, A>
1256where
1257 T: 'a + Eq + Hash + Copy,
1258 S: BuildHasher,
1259 A: Allocator,
1260{
1261 #[inline]
1262 fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
1263 self.extend(iter.into_iter().cloned());
1264 }
1265
1266 #[inline]
1267 fn extend_one(&mut self, &item: &'a T) {
1268 self.base.insert(item);
1269 }
1270
1271 #[inline]
1272 fn extend_reserve(&mut self, additional: usize) {
1273 Extend::<T>::extend_reserve(self, additional)
1274 }
1275}
1276
1277#[stable(feature = "rust1", since = "1.0.0")]
1278#[rustc_const_unstable(feature = "const_default", issue = "143894")]
1279impl<T, S> const Default for HashSet<T, S>
1280where
1281 S: [const] Default,
1282{
1283 /// Creates an empty `HashSet<T, S>` with the `Default` value for the hasher.
1284 #[inline]
1285 fn default() -> HashSet<T, S> {
1286 HashSet { base: base::HashSet::with_hasher(Default::default()) }
1287 }
1288}
1289
1290#[stable(feature = "rust1", since = "1.0.0")]
1291impl<T, S> BitOr<&HashSet<T, S>> for &HashSet<T, S>
1292where
1293 T: Eq + Hash + Clone,
1294 S: BuildHasher + Default,
1295{
1296 type Output = HashSet<T, S>;
1297
1298 /// Returns the union of `self` and `rhs` as a new `HashSet<T, S>`.
1299 ///
1300 /// # Examples
1301 ///
1302 /// ```
1303 /// use std::collections::HashSet;
1304 ///
1305 /// let a = HashSet::from([1, 2, 3]);
1306 /// let b = HashSet::from([3, 4, 5]);
1307 ///
1308 /// let set = &a | &b;
1309 ///
1310 /// let mut i = 0;
1311 /// let expected = [1, 2, 3, 4, 5];
1312 /// for x in &set {
1313 /// assert!(expected.contains(x));
1314 /// i += 1;
1315 /// }
1316 /// assert_eq!(i, expected.len());
1317 /// ```
1318 fn bitor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
1319 self.union(rhs).cloned().collect()
1320 }
1321}
1322
1323#[stable(feature = "rust1", since = "1.0.0")]
1324impl<T, S> BitAnd<&HashSet<T, S>> for &HashSet<T, S>
1325where
1326 T: Eq + Hash + Clone,
1327 S: BuildHasher + Default,
1328{
1329 type Output = HashSet<T, S>;
1330
1331 /// Returns the intersection of `self` and `rhs` as a new `HashSet<T, S>`.
1332 ///
1333 /// # Examples
1334 ///
1335 /// ```
1336 /// use std::collections::HashSet;
1337 ///
1338 /// let a = HashSet::from([1, 2, 3]);
1339 /// let b = HashSet::from([2, 3, 4]);
1340 ///
1341 /// let set = &a & &b;
1342 ///
1343 /// let mut i = 0;
1344 /// let expected = [2, 3];
1345 /// for x in &set {
1346 /// assert!(expected.contains(x));
1347 /// i += 1;
1348 /// }
1349 /// assert_eq!(i, expected.len());
1350 /// ```
1351 fn bitand(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
1352 self.intersection(rhs).cloned().collect()
1353 }
1354}
1355
1356#[stable(feature = "rust1", since = "1.0.0")]
1357impl<T, S> BitXor<&HashSet<T, S>> for &HashSet<T, S>
1358where
1359 T: Eq + Hash + Clone,
1360 S: BuildHasher + Default,
1361{
1362 type Output = HashSet<T, S>;
1363
1364 /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet<T, S>`.
1365 ///
1366 /// # Examples
1367 ///
1368 /// ```
1369 /// use std::collections::HashSet;
1370 ///
1371 /// let a = HashSet::from([1, 2, 3]);
1372 /// let b = HashSet::from([3, 4, 5]);
1373 ///
1374 /// let set = &a ^ &b;
1375 ///
1376 /// let mut i = 0;
1377 /// let expected = [1, 2, 4, 5];
1378 /// for x in &set {
1379 /// assert!(expected.contains(x));
1380 /// i += 1;
1381 /// }
1382 /// assert_eq!(i, expected.len());
1383 /// ```
1384 fn bitxor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
1385 self.symmetric_difference(rhs).cloned().collect()
1386 }
1387}
1388
1389#[stable(feature = "rust1", since = "1.0.0")]
1390impl<T, S> Sub<&HashSet<T, S>> for &HashSet<T, S>
1391where
1392 T: Eq + Hash + Clone,
1393 S: BuildHasher + Default,
1394{
1395 type Output = HashSet<T, S>;
1396
1397 /// Returns the difference of `self` and `rhs` as a new `HashSet<T, S>`.
1398 ///
1399 /// # Examples
1400 ///
1401 /// ```
1402 /// use std::collections::HashSet;
1403 ///
1404 /// let a = HashSet::from([1, 2, 3]);
1405 /// let b = HashSet::from([3, 4, 5]);
1406 ///
1407 /// let set = &a - &b;
1408 ///
1409 /// let mut i = 0;
1410 /// let expected = [1, 2];
1411 /// for x in &set {
1412 /// assert!(expected.contains(x));
1413 /// i += 1;
1414 /// }
1415 /// assert_eq!(i, expected.len());
1416 /// ```
1417 fn sub(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
1418 self.difference(rhs).cloned().collect()
1419 }
1420}
1421
1422/// An iterator over the items of a `HashSet`.
1423///
1424/// This `struct` is created by the [`iter`] method on [`HashSet`].
1425/// See its documentation for more.
1426///
1427/// [`iter`]: HashSet::iter
1428///
1429/// # Examples
1430///
1431/// ```
1432/// use std::collections::HashSet;
1433///
1434/// let a = HashSet::from([1, 2, 3]);
1435///
1436/// let mut iter = a.iter();
1437/// ```
1438#[stable(feature = "rust1", since = "1.0.0")]
1439#[cfg_attr(not(test), rustc_diagnostic_item = "hashset_iter_ty")]
1440pub struct Iter<'a, K: 'a> {
1441 base: base::Iter<'a, K>,
1442}
1443
1444#[stable(feature = "default_iters_hash", since = "1.83.0")]
1445impl<K> Default for Iter<'_, K> {
1446 #[inline]
1447 fn default() -> Self {
1448 Iter { base: Default::default() }
1449 }
1450}
1451
1452/// An owning iterator over the items of a `HashSet`.
1453///
1454/// This `struct` is created by the [`into_iter`] method on [`HashSet`]
1455/// (provided by the [`IntoIterator`] trait). See its documentation for more.
1456///
1457/// [`into_iter`]: IntoIterator::into_iter
1458///
1459/// # Examples
1460///
1461/// ```
1462/// use std::collections::HashSet;
1463///
1464/// let a = HashSet::from([1, 2, 3]);
1465///
1466/// let mut iter = a.into_iter();
1467/// ```
1468#[stable(feature = "rust1", since = "1.0.0")]
1469pub struct IntoIter<
1470 K,
1471 #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
1472> {
1473 base: base::IntoIter<K, A>,
1474}
1475
1476#[stable(feature = "default_iters_hash", since = "1.83.0")]
1477impl<K> Default for IntoIter<K> {
1478 #[inline]
1479 fn default() -> Self {
1480 IntoIter { base: Default::default() }
1481 }
1482}
1483
1484/// A draining iterator over the items of a `HashSet`.
1485///
1486/// This `struct` is created by the [`drain`] method on [`HashSet`].
1487/// See its documentation for more.
1488///
1489/// [`drain`]: HashSet::drain
1490///
1491/// # Examples
1492///
1493/// ```
1494/// use std::collections::HashSet;
1495///
1496/// let mut a = HashSet::from([1, 2, 3]);
1497///
1498/// let mut drain = a.drain();
1499/// ```
1500#[stable(feature = "rust1", since = "1.0.0")]
1501#[cfg_attr(not(test), rustc_diagnostic_item = "hashset_drain_ty")]
1502pub struct Drain<
1503 'a,
1504 K: 'a,
1505 #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
1506> {
1507 base: base::Drain<'a, K, A>,
1508}
1509
1510/// A draining, filtering iterator over the items of a `HashSet`.
1511///
1512/// This `struct` is created by the [`extract_if`] method on [`HashSet`].
1513///
1514/// [`extract_if`]: HashSet::extract_if
1515///
1516/// # Examples
1517///
1518/// ```
1519/// use std::collections::HashSet;
1520///
1521/// let mut a = HashSet::from([1, 2, 3]);
1522///
1523/// let mut extract_ifed = a.extract_if(|v| v % 2 == 0);
1524/// ```
1525#[stable(feature = "hash_extract_if", since = "1.88.0")]
1526#[must_use = "iterators are lazy and do nothing unless consumed; \
1527 use `retain` to remove and discard elements"]
1528pub struct ExtractIf<
1529 'a,
1530 K,
1531 F,
1532 #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
1533> {
1534 base: base::ExtractIf<'a, K, F, A>,
1535}
1536
1537/// A lazy iterator producing elements in the intersection of `HashSet`s.
1538///
1539/// This `struct` is created by the [`intersection`] method on [`HashSet`].
1540/// See its documentation for more.
1541///
1542/// [`intersection`]: HashSet::intersection
1543///
1544/// # Examples
1545///
1546/// ```
1547/// use std::collections::HashSet;
1548///
1549/// let a = HashSet::from([1, 2, 3]);
1550/// let b = HashSet::from([4, 2, 3, 4]);
1551///
1552/// let mut intersection = a.intersection(&b);
1553/// ```
1554#[must_use = "this returns the intersection as an iterator, \
1555 without modifying either input set"]
1556#[stable(feature = "rust1", since = "1.0.0")]
1557pub struct Intersection<
1558 'a,
1559 T: 'a,
1560 S: 'a,
1561 #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
1562> {
1563 // iterator of the first set
1564 iter: Iter<'a, T>,
1565 // the second set
1566 other: &'a HashSet<T, S, A>,
1567}
1568
1569/// A lazy iterator producing elements in the difference of `HashSet`s.
1570///
1571/// This `struct` is created by the [`difference`] method on [`HashSet`].
1572/// See its documentation for more.
1573///
1574/// [`difference`]: HashSet::difference
1575///
1576/// # Examples
1577///
1578/// ```
1579/// use std::collections::HashSet;
1580///
1581/// let a = HashSet::from([1, 2, 3]);
1582/// let b = HashSet::from([4, 2, 3, 4]);
1583///
1584/// let mut difference = a.difference(&b);
1585/// ```
1586#[must_use = "this returns the difference as an iterator, \
1587 without modifying either input set"]
1588#[stable(feature = "rust1", since = "1.0.0")]
1589pub struct Difference<
1590 'a,
1591 T: 'a,
1592 S: 'a,
1593 #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
1594> {
1595 // iterator of the first set
1596 iter: Iter<'a, T>,
1597 // the second set
1598 other: &'a HashSet<T, S, A>,
1599}
1600
1601/// A lazy iterator producing elements in the symmetric difference of `HashSet`s.
1602///
1603/// This `struct` is created by the [`symmetric_difference`] method on
1604/// [`HashSet`]. See its documentation for more.
1605///
1606/// [`symmetric_difference`]: HashSet::symmetric_difference
1607///
1608/// # Examples
1609///
1610/// ```
1611/// use std::collections::HashSet;
1612///
1613/// let a = HashSet::from([1, 2, 3]);
1614/// let b = HashSet::from([4, 2, 3, 4]);
1615///
1616/// let mut intersection = a.symmetric_difference(&b);
1617/// ```
1618#[must_use = "this returns the difference as an iterator, \
1619 without modifying either input set"]
1620#[stable(feature = "rust1", since = "1.0.0")]
1621pub struct SymmetricDifference<
1622 'a,
1623 T: 'a,
1624 S: 'a,
1625 #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
1626> {
1627 iter: Chain<Difference<'a, T, S, A>, Difference<'a, T, S, A>>,
1628}
1629
1630/// A lazy iterator producing elements in the union of `HashSet`s.
1631///
1632/// This `struct` is created by the [`union`] method on [`HashSet`].
1633/// See its documentation for more.
1634///
1635/// [`union`]: HashSet::union
1636///
1637/// # Examples
1638///
1639/// ```
1640/// use std::collections::HashSet;
1641///
1642/// let a = HashSet::from([1, 2, 3]);
1643/// let b = HashSet::from([4, 2, 3, 4]);
1644///
1645/// let mut union_iter = a.union(&b);
1646/// ```
1647#[must_use = "this returns the union as an iterator, \
1648 without modifying either input set"]
1649#[stable(feature = "rust1", since = "1.0.0")]
1650pub struct Union<
1651 'a,
1652 T: 'a,
1653 S: 'a,
1654 #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
1655> {
1656 iter: Chain<Iter<'a, T>, Difference<'a, T, S, A>>,
1657}
1658
1659#[stable(feature = "rust1", since = "1.0.0")]
1660impl<'a, T, S, A: Allocator> IntoIterator for &'a HashSet<T, S, A> {
1661 type Item = &'a T;
1662 type IntoIter = Iter<'a, T>;
1663
1664 #[inline]
1665 #[rustc_lint_query_instability]
1666 fn into_iter(self) -> Iter<'a, T> {
1667 self.iter()
1668 }
1669}
1670
1671#[stable(feature = "rust1", since = "1.0.0")]
1672impl<T, S, A: Allocator> IntoIterator for HashSet<T, S, A> {
1673 type Item = T;
1674 type IntoIter = IntoIter<T, A>;
1675
1676 /// Creates a consuming iterator, that is, one that moves each value out
1677 /// of the set in arbitrary order. The set cannot be used after calling
1678 /// this.
1679 ///
1680 /// # Examples
1681 ///
1682 /// ```
1683 /// use std::collections::HashSet;
1684 /// let mut set = HashSet::new();
1685 /// set.insert("a".to_string());
1686 /// set.insert("b".to_string());
1687 ///
1688 /// // Not possible to collect to a Vec<String> with a regular `.iter()`.
1689 /// let v: Vec<String> = set.into_iter().collect();
1690 ///
1691 /// // Will print in an arbitrary order.
1692 /// for x in &v {
1693 /// println!("{x}");
1694 /// }
1695 /// ```
1696 #[inline]
1697 #[rustc_lint_query_instability]
1698 fn into_iter(self) -> IntoIter<T, A> {
1699 IntoIter { base: self.base.into_iter() }
1700 }
1701}
1702
1703#[stable(feature = "rust1", since = "1.0.0")]
1704impl<K> Clone for Iter<'_, K> {
1705 #[inline]
1706 fn clone(&self) -> Self {
1707 Iter { base: self.base.clone() }
1708 }
1709}
1710#[stable(feature = "rust1", since = "1.0.0")]
1711impl<'a, K> Iterator for Iter<'a, K> {
1712 type Item = &'a K;
1713
1714 #[inline]
1715 fn next(&mut self) -> Option<&'a K> {
1716 self.base.next()
1717 }
1718 #[inline]
1719 fn size_hint(&self) -> (usize, Option<usize>) {
1720 self.base.size_hint()
1721 }
1722 #[inline]
1723 fn count(self) -> usize {
1724 self.base.len()
1725 }
1726 #[inline]
1727 fn fold<B, F>(self, init: B, f: F) -> B
1728 where
1729 Self: Sized,
1730 F: FnMut(B, Self::Item) -> B,
1731 {
1732 self.base.fold(init, f)
1733 }
1734}
1735#[stable(feature = "rust1", since = "1.0.0")]
1736impl<K> ExactSizeIterator for Iter<'_, K> {
1737 #[inline]
1738 fn len(&self) -> usize {
1739 self.base.len()
1740 }
1741}
1742#[stable(feature = "fused", since = "1.26.0")]
1743impl<K> FusedIterator for Iter<'_, K> {}
1744
1745#[stable(feature = "std_debug", since = "1.16.0")]
1746impl<K: fmt::Debug> fmt::Debug for Iter<'_, K> {
1747 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1748 f.debug_list().entries(self.clone()).finish()
1749 }
1750}
1751
1752#[stable(feature = "rust1", since = "1.0.0")]
1753impl<K, A: Allocator> Iterator for IntoIter<K, A> {
1754 type Item = K;
1755
1756 #[inline]
1757 fn next(&mut self) -> Option<K> {
1758 self.base.next()
1759 }
1760 #[inline]
1761 fn size_hint(&self) -> (usize, Option<usize>) {
1762 self.base.size_hint()
1763 }
1764 #[inline]
1765 fn count(self) -> usize {
1766 self.base.len()
1767 }
1768 #[inline]
1769 fn fold<B, F>(self, init: B, f: F) -> B
1770 where
1771 Self: Sized,
1772 F: FnMut(B, Self::Item) -> B,
1773 {
1774 self.base.fold(init, f)
1775 }
1776}
1777#[stable(feature = "rust1", since = "1.0.0")]
1778impl<K, A: Allocator> ExactSizeIterator for IntoIter<K, A> {
1779 #[inline]
1780 fn len(&self) -> usize {
1781 self.base.len()
1782 }
1783}
1784#[stable(feature = "fused", since = "1.26.0")]
1785impl<K, A: Allocator> FusedIterator for IntoIter<K, A> {}
1786
1787#[stable(feature = "std_debug", since = "1.16.0")]
1788impl<K: fmt::Debug, A: Allocator> fmt::Debug for IntoIter<K, A> {
1789 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1790 fmt::Debug::fmt(&self.base, f)
1791 }
1792}
1793
1794#[stable(feature = "rust1", since = "1.0.0")]
1795impl<'a, K, A: Allocator> Iterator for Drain<'a, K, A> {
1796 type Item = K;
1797
1798 #[inline]
1799 fn next(&mut self) -> Option<K> {
1800 self.base.next()
1801 }
1802 #[inline]
1803 fn size_hint(&self) -> (usize, Option<usize>) {
1804 self.base.size_hint()
1805 }
1806 #[inline]
1807 fn fold<B, F>(self, init: B, f: F) -> B
1808 where
1809 Self: Sized,
1810 F: FnMut(B, Self::Item) -> B,
1811 {
1812 self.base.fold(init, f)
1813 }
1814}
1815#[stable(feature = "rust1", since = "1.0.0")]
1816impl<K, A: Allocator> ExactSizeIterator for Drain<'_, K, A> {
1817 #[inline]
1818 fn len(&self) -> usize {
1819 self.base.len()
1820 }
1821}
1822#[stable(feature = "fused", since = "1.26.0")]
1823impl<K, A: Allocator> FusedIterator for Drain<'_, K, A> {}
1824
1825#[stable(feature = "std_debug", since = "1.16.0")]
1826impl<K: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, K, A> {
1827 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1828 fmt::Debug::fmt(&self.base, f)
1829 }
1830}
1831
1832#[stable(feature = "hash_extract_if", since = "1.88.0")]
1833impl<K, F, A: Allocator> Iterator for ExtractIf<'_, K, F, A>
1834where
1835 F: FnMut(&K) -> bool,
1836{
1837 type Item = K;
1838
1839 #[inline]
1840 fn next(&mut self) -> Option<K> {
1841 self.base.next()
1842 }
1843 #[inline]
1844 fn size_hint(&self) -> (usize, Option<usize>) {
1845 self.base.size_hint()
1846 }
1847}
1848
1849#[stable(feature = "hash_extract_if", since = "1.88.0")]
1850impl<K, F, A: Allocator> FusedIterator for ExtractIf<'_, K, F, A> where F: FnMut(&K) -> bool {}
1851
1852#[stable(feature = "hash_extract_if", since = "1.88.0")]
1853impl<K, F, A: Allocator> fmt::Debug for ExtractIf<'_, K, F, A>
1854where
1855 K: fmt::Debug,
1856{
1857 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1858 f.debug_struct("ExtractIf").finish_non_exhaustive()
1859 }
1860}
1861
1862#[stable(feature = "rust1", since = "1.0.0")]
1863impl<T, S, A: Allocator> Clone for Intersection<'_, T, S, A> {
1864 #[inline]
1865 fn clone(&self) -> Self {
1866 Intersection { iter: self.iter.clone(), ..*self }
1867 }
1868}
1869
1870#[stable(feature = "rust1", since = "1.0.0")]
1871impl<'a, T, S, A> Iterator for Intersection<'a, T, S, A>
1872where
1873 T: Eq + Hash,
1874 S: BuildHasher,
1875 A: Allocator,
1876{
1877 type Item = &'a T;
1878
1879 #[inline]
1880 fn next(&mut self) -> Option<&'a T> {
1881 loop {
1882 let elt = self.iter.next()?;
1883 if self.other.contains(elt) {
1884 return Some(elt);
1885 }
1886 }
1887 }
1888
1889 #[inline]
1890 fn size_hint(&self) -> (usize, Option<usize>) {
1891 let (_, upper) = self.iter.size_hint();
1892 (0, upper)
1893 }
1894
1895 #[inline]
1896 fn fold<B, F>(self, init: B, mut f: F) -> B
1897 where
1898 Self: Sized,
1899 F: FnMut(B, Self::Item) -> B,
1900 {
1901 self.iter.fold(init, |acc, elt| if self.other.contains(elt) { f(acc, elt) } else { acc })
1902 }
1903}
1904
1905#[stable(feature = "std_debug", since = "1.16.0")]
1906impl<T, S, A> fmt::Debug for Intersection<'_, T, S, A>
1907where
1908 T: fmt::Debug + Eq + Hash,
1909 S: BuildHasher,
1910 A: Allocator,
1911{
1912 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1913 f.debug_list().entries(self.clone()).finish()
1914 }
1915}
1916
1917#[stable(feature = "fused", since = "1.26.0")]
1918impl<T, S, A> FusedIterator for Intersection<'_, T, S, A>
1919where
1920 T: Eq + Hash,
1921 S: BuildHasher,
1922 A: Allocator,
1923{
1924}
1925
1926#[stable(feature = "rust1", since = "1.0.0")]
1927impl<T, S, A: Allocator> Clone for Difference<'_, T, S, A> {
1928 #[inline]
1929 fn clone(&self) -> Self {
1930 Difference { iter: self.iter.clone(), ..*self }
1931 }
1932}
1933
1934#[stable(feature = "rust1", since = "1.0.0")]
1935impl<'a, T, S, A> Iterator for Difference<'a, T, S, A>
1936where
1937 T: Eq + Hash,
1938 S: BuildHasher,
1939 A: Allocator,
1940{
1941 type Item = &'a T;
1942
1943 #[inline]
1944 fn next(&mut self) -> Option<&'a T> {
1945 loop {
1946 let elt = self.iter.next()?;
1947 if !self.other.contains(elt) {
1948 return Some(elt);
1949 }
1950 }
1951 }
1952
1953 #[inline]
1954 fn size_hint(&self) -> (usize, Option<usize>) {
1955 let (_, upper) = self.iter.size_hint();
1956 (0, upper)
1957 }
1958
1959 #[inline]
1960 fn fold<B, F>(self, init: B, mut f: F) -> B
1961 where
1962 Self: Sized,
1963 F: FnMut(B, Self::Item) -> B,
1964 {
1965 self.iter.fold(init, |acc, elt| if self.other.contains(elt) { acc } else { f(acc, elt) })
1966 }
1967}
1968
1969#[stable(feature = "fused", since = "1.26.0")]
1970impl<T, S, A> FusedIterator for Difference<'_, T, S, A>
1971where
1972 T: Eq + Hash,
1973 S: BuildHasher,
1974 A: Allocator,
1975{
1976}
1977
1978#[stable(feature = "std_debug", since = "1.16.0")]
1979impl<T, S, A> fmt::Debug for Difference<'_, T, S, A>
1980where
1981 T: fmt::Debug + Eq + Hash,
1982 S: BuildHasher,
1983 A: Allocator,
1984{
1985 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1986 f.debug_list().entries(self.clone()).finish()
1987 }
1988}
1989
1990#[stable(feature = "rust1", since = "1.0.0")]
1991impl<T, S, A: Allocator> Clone for SymmetricDifference<'_, T, S, A> {
1992 #[inline]
1993 fn clone(&self) -> Self {
1994 SymmetricDifference { iter: self.iter.clone() }
1995 }
1996}
1997
1998#[stable(feature = "rust1", since = "1.0.0")]
1999impl<'a, T, S, A> Iterator for SymmetricDifference<'a, T, S, A>
2000where
2001 T: Eq + Hash,
2002 S: BuildHasher,
2003 A: Allocator,
2004{
2005 type Item = &'a T;
2006
2007 #[inline]
2008 fn next(&mut self) -> Option<&'a T> {
2009 self.iter.next()
2010 }
2011 #[inline]
2012 fn size_hint(&self) -> (usize, Option<usize>) {
2013 self.iter.size_hint()
2014 }
2015 #[inline]
2016 fn fold<B, F>(self, init: B, f: F) -> B
2017 where
2018 Self: Sized,
2019 F: FnMut(B, Self::Item) -> B,
2020 {
2021 self.iter.fold(init, f)
2022 }
2023}
2024
2025#[stable(feature = "fused", since = "1.26.0")]
2026impl<T, S, A> FusedIterator for SymmetricDifference<'_, T, S, A>
2027where
2028 T: Eq + Hash,
2029 S: BuildHasher,
2030 A: Allocator,
2031{
2032}
2033
2034#[stable(feature = "std_debug", since = "1.16.0")]
2035impl<T, S, A> fmt::Debug for SymmetricDifference<'_, 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
2046#[stable(feature = "rust1", since = "1.0.0")]
2047impl<T, S, A: Allocator> Clone for Union<'_, T, S, A> {
2048 #[inline]
2049 fn clone(&self) -> Self {
2050 Union { iter: self.iter.clone() }
2051 }
2052}
2053
2054#[stable(feature = "fused", since = "1.26.0")]
2055impl<T, S, A: Allocator> FusedIterator for Union<'_, T, S, A>
2056where
2057 T: Eq + Hash,
2058 S: BuildHasher,
2059{
2060}
2061
2062#[stable(feature = "std_debug", since = "1.16.0")]
2063impl<T, S, A: Allocator> fmt::Debug for Union<'_, T, S, A>
2064where
2065 T: fmt::Debug + Eq + Hash,
2066 S: BuildHasher,
2067 A: Allocator,
2068{
2069 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2070 f.debug_list().entries(self.clone()).finish()
2071 }
2072}
2073
2074#[stable(feature = "rust1", since = "1.0.0")]
2075impl<'a, T, S, A> Iterator for Union<'a, T, S, A>
2076where
2077 T: Eq + Hash,
2078 S: BuildHasher,
2079 A: Allocator,
2080{
2081 type Item = &'a T;
2082
2083 #[inline]
2084 fn next(&mut self) -> Option<&'a T> {
2085 self.iter.next()
2086 }
2087 #[inline]
2088 fn size_hint(&self) -> (usize, Option<usize>) {
2089 self.iter.size_hint()
2090 }
2091 #[inline]
2092 fn count(self) -> usize {
2093 self.iter.count()
2094 }
2095 #[inline]
2096 fn fold<B, F>(self, init: B, f: F) -> B
2097 where
2098 Self: Sized,
2099 F: FnMut(B, Self::Item) -> B,
2100 {
2101 self.iter.fold(init, f)
2102 }
2103}
2104
2105/// A view into a single entry in a set, which may either be vacant or occupied.
2106///
2107/// This `enum` is constructed from the [`entry`] method on [`HashSet`].
2108///
2109/// [`HashSet`]: struct.HashSet.html
2110/// [`entry`]: struct.HashSet.html#method.entry
2111///
2112/// # Examples
2113///
2114/// ```
2115/// #![feature(hash_set_entry)]
2116///
2117/// use std::collections::hash_set::HashSet;
2118///
2119/// let mut set = HashSet::new();
2120/// set.extend(["a", "b", "c"]);
2121/// assert_eq!(set.len(), 3);
2122///
2123/// // Existing value (insert)
2124/// let entry = set.entry("a");
2125/// let _raw_o = entry.insert();
2126/// assert_eq!(set.len(), 3);
2127/// // Nonexistent value (insert)
2128/// set.entry("d").insert();
2129///
2130/// // Existing value (or_insert)
2131/// set.entry("b").or_insert();
2132/// // Nonexistent value (or_insert)
2133/// set.entry("e").or_insert();
2134///
2135/// println!("Our HashSet: {:?}", set);
2136///
2137/// let mut vec: Vec<_> = set.iter().copied().collect();
2138/// // The `Iter` iterator produces items in arbitrary order, so the
2139/// // items must be sorted to test them against a sorted array.
2140/// vec.sort_unstable();
2141/// assert_eq!(vec, ["a", "b", "c", "d", "e"]);
2142/// ```
2143#[unstable(feature = "hash_set_entry", issue = "60896")]
2144pub enum Entry<
2145 'a,
2146 T,
2147 S,
2148 #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
2149> {
2150 /// An occupied entry.
2151 ///
2152 /// # Examples
2153 ///
2154 /// ```
2155 /// #![feature(hash_set_entry)]
2156 ///
2157 /// use std::collections::hash_set::{Entry, HashSet};
2158 ///
2159 /// let mut set = HashSet::from(["a", "b"]);
2160 ///
2161 /// match set.entry("a") {
2162 /// Entry::Vacant(_) => unreachable!(),
2163 /// Entry::Occupied(_) => { }
2164 /// }
2165 /// ```
2166 Occupied(OccupiedEntry<'a, T, S, A>),
2167
2168 /// A vacant entry.
2169 ///
2170 /// # Examples
2171 ///
2172 /// ```
2173 /// #![feature(hash_set_entry)]
2174 ///
2175 /// use std::collections::hash_set::{Entry, HashSet};
2176 ///
2177 /// let mut set = HashSet::new();
2178 ///
2179 /// match set.entry("a") {
2180 /// Entry::Occupied(_) => unreachable!(),
2181 /// Entry::Vacant(_) => { }
2182 /// }
2183 /// ```
2184 Vacant(VacantEntry<'a, T, S, A>),
2185}
2186
2187#[unstable(feature = "hash_set_entry", issue = "60896")]
2188impl<T: fmt::Debug, S, A: Allocator> fmt::Debug for Entry<'_, T, S, A> {
2189 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2190 match *self {
2191 Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
2192 Entry::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
2193 }
2194 }
2195}
2196
2197/// A view into an occupied entry in a `HashSet`.
2198/// It is part of the [`Entry`] enum.
2199///
2200/// [`Entry`]: enum.Entry.html
2201///
2202/// # Examples
2203///
2204/// ```
2205/// #![feature(hash_set_entry)]
2206///
2207/// use std::collections::hash_set::{Entry, HashSet};
2208///
2209/// let mut set = HashSet::new();
2210/// set.extend(["a", "b", "c"]);
2211///
2212/// let _entry_o = set.entry("a").insert();
2213/// assert_eq!(set.len(), 3);
2214///
2215/// // Existing key
2216/// match set.entry("a") {
2217/// Entry::Vacant(_) => unreachable!(),
2218/// Entry::Occupied(view) => {
2219/// assert_eq!(view.get(), &"a");
2220/// }
2221/// }
2222///
2223/// assert_eq!(set.len(), 3);
2224///
2225/// // Existing key (take)
2226/// match set.entry("c") {
2227/// Entry::Vacant(_) => unreachable!(),
2228/// Entry::Occupied(view) => {
2229/// assert_eq!(view.remove(), "c");
2230/// }
2231/// }
2232/// assert_eq!(set.get(&"c"), None);
2233/// assert_eq!(set.len(), 2);
2234/// ```
2235#[unstable(feature = "hash_set_entry", issue = "60896")]
2236pub struct OccupiedEntry<
2237 'a,
2238 T,
2239 S,
2240 #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
2241> {
2242 base: base::OccupiedEntry<'a, T, S, A>,
2243}
2244
2245#[unstable(feature = "hash_set_entry", issue = "60896")]
2246impl<T: fmt::Debug, S, A: Allocator> fmt::Debug for OccupiedEntry<'_, T, S, A> {
2247 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2248 f.debug_struct("OccupiedEntry").field("value", self.get()).finish()
2249 }
2250}
2251
2252/// A view into a vacant entry in a `HashSet`.
2253/// It is part of the [`Entry`] enum.
2254///
2255/// [`Entry`]: enum.Entry.html
2256///
2257/// # Examples
2258///
2259/// ```
2260/// #![feature(hash_set_entry)]
2261///
2262/// use std::collections::hash_set::{Entry, HashSet};
2263///
2264/// let mut set = HashSet::<&str>::new();
2265///
2266/// let entry_v = match set.entry("a") {
2267/// Entry::Vacant(view) => view,
2268/// Entry::Occupied(_) => unreachable!(),
2269/// };
2270/// entry_v.insert();
2271/// assert!(set.contains("a") && set.len() == 1);
2272///
2273/// // Nonexistent key (insert)
2274/// match set.entry("b") {
2275/// Entry::Vacant(view) => view.insert(),
2276/// Entry::Occupied(_) => unreachable!(),
2277/// }
2278/// assert!(set.contains("b") && set.len() == 2);
2279/// ```
2280#[unstable(feature = "hash_set_entry", issue = "60896")]
2281pub struct VacantEntry<
2282 'a,
2283 T,
2284 S,
2285 #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
2286> {
2287 base: base::VacantEntry<'a, T, S, A>,
2288}
2289
2290#[unstable(feature = "hash_set_entry", issue = "60896")]
2291impl<T: fmt::Debug, S, A: Allocator> fmt::Debug for VacantEntry<'_, T, S, A> {
2292 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2293 f.debug_tuple("VacantEntry").field(self.get()).finish()
2294 }
2295}
2296
2297impl<'a, T, S, A: Allocator> Entry<'a, T, S, A> {
2298 /// Sets the value of the entry, and returns an OccupiedEntry.
2299 ///
2300 /// # Examples
2301 ///
2302 /// ```
2303 /// #![feature(hash_set_entry)]
2304 ///
2305 /// use std::collections::HashSet;
2306 ///
2307 /// let mut set = HashSet::new();
2308 /// let entry = set.entry("horseyland").insert();
2309 ///
2310 /// assert_eq!(entry.get(), &"horseyland");
2311 /// ```
2312 #[inline]
2313 #[unstable(feature = "hash_set_entry", issue = "60896")]
2314 pub fn insert(self) -> OccupiedEntry<'a, T, S, A>
2315 where
2316 T: Hash,
2317 S: BuildHasher,
2318 {
2319 match self {
2320 Entry::Occupied(entry) => entry,
2321 Entry::Vacant(entry) => entry.insert_entry(),
2322 }
2323 }
2324
2325 /// Ensures a value is in the entry by inserting if it was vacant.
2326 ///
2327 /// # Examples
2328 ///
2329 /// ```
2330 /// #![feature(hash_set_entry)]
2331 ///
2332 /// use std::collections::HashSet;
2333 ///
2334 /// let mut set = HashSet::new();
2335 ///
2336 /// // nonexistent key
2337 /// set.entry("poneyland").or_insert();
2338 /// assert!(set.contains("poneyland"));
2339 ///
2340 /// // existing key
2341 /// set.entry("poneyland").or_insert();
2342 /// assert!(set.contains("poneyland"));
2343 /// assert_eq!(set.len(), 1);
2344 /// ```
2345 #[inline]
2346 #[unstable(feature = "hash_set_entry", issue = "60896")]
2347 pub fn or_insert(self)
2348 where
2349 T: Hash,
2350 S: BuildHasher,
2351 {
2352 if let Entry::Vacant(entry) = self {
2353 entry.insert();
2354 }
2355 }
2356
2357 /// Returns a reference to this entry's value.
2358 ///
2359 /// # Examples
2360 ///
2361 /// ```
2362 /// #![feature(hash_set_entry)]
2363 ///
2364 /// use std::collections::HashSet;
2365 ///
2366 /// let mut set = HashSet::new();
2367 /// set.entry("poneyland").or_insert();
2368 ///
2369 /// // existing key
2370 /// assert_eq!(set.entry("poneyland").get(), &"poneyland");
2371 /// // nonexistent key
2372 /// assert_eq!(set.entry("horseland").get(), &"horseland");
2373 /// ```
2374 #[inline]
2375 #[unstable(feature = "hash_set_entry", issue = "60896")]
2376 pub fn get(&self) -> &T {
2377 match *self {
2378 Entry::Occupied(ref entry) => entry.get(),
2379 Entry::Vacant(ref entry) => entry.get(),
2380 }
2381 }
2382}
2383
2384impl<T, S, A: Allocator> OccupiedEntry<'_, T, S, A> {
2385 /// Gets a reference to the value in the entry.
2386 ///
2387 /// # Examples
2388 ///
2389 /// ```
2390 /// #![feature(hash_set_entry)]
2391 ///
2392 /// use std::collections::hash_set::{Entry, HashSet};
2393 ///
2394 /// let mut set = HashSet::new();
2395 /// set.entry("poneyland").or_insert();
2396 ///
2397 /// match set.entry("poneyland") {
2398 /// Entry::Vacant(_) => panic!(),
2399 /// Entry::Occupied(entry) => assert_eq!(entry.get(), &"poneyland"),
2400 /// }
2401 /// ```
2402 #[inline]
2403 #[unstable(feature = "hash_set_entry", issue = "60896")]
2404 pub fn get(&self) -> &T {
2405 self.base.get()
2406 }
2407
2408 /// Takes the value out of the entry, and returns it.
2409 /// Keeps the allocated memory for reuse.
2410 ///
2411 /// # Examples
2412 ///
2413 /// ```
2414 /// #![feature(hash_set_entry)]
2415 ///
2416 /// use std::collections::HashSet;
2417 /// use std::collections::hash_set::Entry;
2418 ///
2419 /// let mut set = HashSet::new();
2420 /// // The set is empty
2421 /// assert!(set.is_empty() && set.capacity() == 0);
2422 ///
2423 /// set.entry("poneyland").or_insert();
2424 /// let capacity_before_remove = set.capacity();
2425 ///
2426 /// if let Entry::Occupied(o) = set.entry("poneyland") {
2427 /// assert_eq!(o.remove(), "poneyland");
2428 /// }
2429 ///
2430 /// assert_eq!(set.contains("poneyland"), false);
2431 /// // Now set hold none elements but capacity is equal to the old one
2432 /// assert!(set.len() == 0 && set.capacity() == capacity_before_remove);
2433 /// ```
2434 #[inline]
2435 #[unstable(feature = "hash_set_entry", issue = "60896")]
2436 pub fn remove(self) -> T {
2437 self.base.remove()
2438 }
2439}
2440
2441impl<'a, T, S, A: Allocator> VacantEntry<'a, T, S, A> {
2442 /// Gets a reference to the value that would be used when inserting
2443 /// through the `VacantEntry`.
2444 ///
2445 /// # Examples
2446 ///
2447 /// ```
2448 /// #![feature(hash_set_entry)]
2449 ///
2450 /// use std::collections::HashSet;
2451 ///
2452 /// let mut set = HashSet::new();
2453 /// assert_eq!(set.entry("poneyland").get(), &"poneyland");
2454 /// ```
2455 #[inline]
2456 #[unstable(feature = "hash_set_entry", issue = "60896")]
2457 pub fn get(&self) -> &T {
2458 self.base.get()
2459 }
2460
2461 /// Take ownership of the value.
2462 ///
2463 /// # Examples
2464 ///
2465 /// ```
2466 /// #![feature(hash_set_entry)]
2467 ///
2468 /// use std::collections::hash_set::{Entry, HashSet};
2469 ///
2470 /// let mut set = HashSet::new();
2471 ///
2472 /// match set.entry("poneyland") {
2473 /// Entry::Occupied(_) => panic!(),
2474 /// Entry::Vacant(v) => assert_eq!(v.into_value(), "poneyland"),
2475 /// }
2476 /// ```
2477 #[inline]
2478 #[unstable(feature = "hash_set_entry", issue = "60896")]
2479 pub fn into_value(self) -> T {
2480 self.base.into_value()
2481 }
2482
2483 /// Sets the value of the entry with the VacantEntry's value.
2484 ///
2485 /// # Examples
2486 ///
2487 /// ```
2488 /// #![feature(hash_set_entry)]
2489 ///
2490 /// use std::collections::HashSet;
2491 /// use std::collections::hash_set::Entry;
2492 ///
2493 /// let mut set = HashSet::new();
2494 ///
2495 /// if let Entry::Vacant(o) = set.entry("poneyland") {
2496 /// o.insert();
2497 /// }
2498 /// assert!(set.contains("poneyland"));
2499 /// ```
2500 #[inline]
2501 #[unstable(feature = "hash_set_entry", issue = "60896")]
2502 pub fn insert(self)
2503 where
2504 T: Hash,
2505 S: BuildHasher,
2506 {
2507 self.base.insert();
2508 }
2509
2510 #[inline]
2511 fn insert_entry(self) -> OccupiedEntry<'a, T, S, A>
2512 where
2513 T: Hash,
2514 S: BuildHasher,
2515 {
2516 OccupiedEntry { base: self.base.insert() }
2517 }
2518}
2519
2520#[allow(dead_code)]
2521fn assert_covariance() {
2522 fn set<'new>(v: HashSet<&'static str>) -> HashSet<&'new str> {
2523 v
2524 }
2525 fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> {
2526 v
2527 }
2528 fn into_iter<'new>(v: IntoIter<&'static str>) -> IntoIter<&'new str> {
2529 v
2530 }
2531 fn difference<'a, 'new>(
2532 v: Difference<'a, &'static str, RandomState>,
2533 ) -> Difference<'a, &'new str, RandomState> {
2534 v
2535 }
2536 fn symmetric_difference<'a, 'new>(
2537 v: SymmetricDifference<'a, &'static str, RandomState>,
2538 ) -> SymmetricDifference<'a, &'new str, RandomState> {
2539 v
2540 }
2541 fn intersection<'a, 'new>(
2542 v: Intersection<'a, &'static str, RandomState>,
2543 ) -> Intersection<'a, &'new str, RandomState> {
2544 v
2545 }
2546 fn union<'a, 'new>(
2547 v: Union<'a, &'static str, RandomState>,
2548 ) -> Union<'a, &'new str, RandomState> {
2549 v
2550 }
2551 fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> {
2552 d
2553 }
2554}