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