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