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}