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}