Skip to main content

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