]> git.proxmox.com Git - rustc.git/blame - library/std/src/collections/hash/set.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / library / std / src / collections / hash / set.rs
CommitLineData
1b1a35ee
XL
1#[cfg(test)]
2mod tests;
3
4use hashbrown::hash_set as base;
5
532ac7d7 6use crate::borrow::Borrow;
e1599b0c 7use crate::collections::TryReserveError;
532ac7d7 8use crate::fmt;
dfeec247 9use crate::hash::{BuildHasher, Hash};
04454e1e 10use crate::iter::{Chain, FusedIterator};
dfeec247 11use crate::ops::{BitAnd, BitOr, BitXor, Sub};
1a4d82fc 12
1b1a35ee 13use super::map::{map_try_reserve_error, RandomState};
1a4d82fc
JJ
14
15// Future Optimization (FIXME!)
532ac7d7 16// ============================
1a4d82fc
JJ
17//
18// Iteration over zero sized values is a noop. There is no need
19// for `bucket.val` in the case of HashSet. I suppose we would need HKT
20// to get rid of it properly.
21
6a06907d 22/// A [hash set] implemented as a `HashMap` where the value is `()`.
d9579d0f 23///
cc61c64b
XL
24/// As with the [`HashMap`] type, a `HashSet` requires that the elements
25/// implement the [`Eq`] and [`Hash`] traits. This can frequently be achieved by
d9579d0f
AL
26/// using `#[derive(PartialEq, Eq, Hash)]`. If you implement these yourself,
27/// it is important that the following property holds:
c34b1796
AL
28///
29/// ```text
30/// k1 == k2 -> hash(k1) == hash(k2)
31/// ```
32///
33/// In other words, if two keys are equal, their hashes must be equal.
1a4d82fc 34///
c34b1796 35///
923072b8
FG
36/// It is a logic error for a key to be modified in such a way that the key's
37/// hash, as determined by the [`Hash`] trait, or its equality, as determined by
38/// the [`Eq`] trait, changes while it is in the map. This is normally only
39/// possible through [`Cell`], [`RefCell`], global state, I/O, or unsafe code.
40/// The behavior resulting from such a logic error is not specified, but will
41/// be encapsulated to the `HashSet` that observed the logic error and not
42/// result in undefined behavior. This could include panics, incorrect results,
43/// aborts, memory leaks, and non-termination.
c34b1796
AL
44///
45/// # Examples
1a4d82fc
JJ
46///
47/// ```
48/// use std::collections::HashSet;
49/// // Type inference lets us omit an explicit type signature (which
94b46f34 50/// // would be `HashSet<String>` in this example).
1a4d82fc
JJ
51/// let mut books = HashSet::new();
52///
53/// // Add some books.
94b46f34
XL
54/// books.insert("A Dance With Dragons".to_string());
55/// books.insert("To Kill a Mockingbird".to_string());
56/// books.insert("The Odyssey".to_string());
57/// books.insert("The Great Gatsby".to_string());
1a4d82fc
JJ
58///
59/// // Check for a specific one.
d9579d0f 60/// if !books.contains("The Winds of Winter") {
1a4d82fc
JJ
61/// println!("We have {} books, but The Winds of Winter ain't one.",
62/// books.len());
63/// }
64///
65/// // Remove a book.
d9579d0f 66/// books.remove("The Odyssey");
1a4d82fc
JJ
67///
68/// // Iterate over everything.
d9579d0f 69/// for book in &books {
5e7ed085 70/// println!("{book}");
1a4d82fc
JJ
71/// }
72/// ```
73///
74/// The easiest way to use `HashSet` with a custom type is to derive
cc61c64b
XL
75/// [`Eq`] and [`Hash`]. We must also derive [`PartialEq`], this will in the
76/// future be implied by [`Eq`].
1a4d82fc
JJ
77///
78/// ```
79/// use std::collections::HashSet;
85aaf69f 80/// #[derive(Hash, Eq, PartialEq, Debug)]
94b46f34
XL
81/// struct Viking {
82/// name: String,
85aaf69f 83/// power: usize,
1a4d82fc
JJ
84/// }
85///
86/// let mut vikings = HashSet::new();
87///
94b46f34
XL
88/// vikings.insert(Viking { name: "Einar".to_string(), power: 9 });
89/// vikings.insert(Viking { name: "Einar".to_string(), power: 9 });
90/// vikings.insert(Viking { name: "Olaf".to_string(), power: 4 });
91/// vikings.insert(Viking { name: "Harald".to_string(), power: 8 });
1a4d82fc
JJ
92///
93/// // Use derived implementation to print the vikings.
d9579d0f 94/// for x in &vikings {
5e7ed085 95/// println!("{x:?}");
1a4d82fc
JJ
96/// }
97/// ```
c30ab7b3 98///
94222f64 99/// A `HashSet` with a known list of items can be initialized from an array:
c30ab7b3
SL
100///
101/// ```
102/// use std::collections::HashSet;
103///
94222f64 104/// let viking_names = HashSet::from(["Einar", "Olaf", "Harald"]);
c30ab7b3 105/// ```
cc61c64b 106///
6a06907d 107/// [hash set]: crate::collections#use-the-set-variant-of-any-of-these-maps-when
1b1a35ee 108/// [`HashMap`]: crate::collections::HashMap
3dfed10e
XL
109/// [`RefCell`]: crate::cell::RefCell
110/// [`Cell`]: crate::cell::Cell
c295e0f8 111#[cfg_attr(not(test), rustc_diagnostic_item = "HashSet")]
85aaf69f 112#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 113pub struct HashSet<T, S = RandomState> {
1b1a35ee 114 base: base::HashSet<T, S>,
1a4d82fc
JJ
115}
116
74b04a01 117impl<T> HashSet<T, RandomState> {
3b2f2976 118 /// Creates an empty `HashSet`.
1a4d82fc 119 ///
ea8adc8c
XL
120 /// The hash set is initially created with a capacity of 0, so it will not allocate until it
121 /// is first inserted into.
122 ///
c34b1796 123 /// # Examples
1a4d82fc
JJ
124 ///
125 /// ```
126 /// use std::collections::HashSet;
3b2f2976 127 /// let set: HashSet<i32> = HashSet::new();
1a4d82fc
JJ
128 /// ```
129 #[inline]
c295e0f8 130 #[must_use]
85aaf69f 131 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 132 pub fn new() -> HashSet<T, RandomState> {
1b1a35ee 133 Default::default()
1a4d82fc
JJ
134 }
135
923072b8 136 /// Creates an empty `HashSet` with at least the specified capacity.
c30ab7b3
SL
137 ///
138 /// The hash set will be able to hold at least `capacity` elements without
923072b8
FG
139 /// reallocating. This method is allowed to allocate for more elements than
140 /// `capacity`. If `capacity` is 0, the hash set will not allocate.
1a4d82fc 141 ///
c34b1796 142 /// # Examples
1a4d82fc
JJ
143 ///
144 /// ```
145 /// use std::collections::HashSet;
3b2f2976
XL
146 /// let set: HashSet<i32> = HashSet::with_capacity(10);
147 /// assert!(set.capacity() >= 10);
1a4d82fc
JJ
148 /// ```
149 #[inline]
c295e0f8 150 #[must_use]
85aaf69f
SL
151 #[stable(feature = "rust1", since = "1.0.0")]
152 pub fn with_capacity(capacity: usize) -> HashSet<T, RandomState> {
1b1a35ee 153 HashSet { base: base::HashSet::with_capacity_and_hasher(capacity, Default::default()) }
1a4d82fc
JJ
154 }
155}
156
9fa01778
XL
157impl<T, S> HashSet<T, S> {
158 /// Returns the number of elements the set can hold without reallocating.
159 ///
160 /// # Examples
161 ///
162 /// ```
163 /// use std::collections::HashSet;
164 /// let set: HashSet<i32> = HashSet::with_capacity(100);
165 /// assert!(set.capacity() >= 100);
166 /// ```
167 #[inline]
168 #[stable(feature = "rust1", since = "1.0.0")]
169 pub fn capacity(&self) -> usize {
1b1a35ee 170 self.base.capacity()
9fa01778
XL
171 }
172
173 /// An iterator visiting all elements in arbitrary order.
174 /// The iterator element type is `&'a T`.
175 ///
176 /// # Examples
177 ///
178 /// ```
179 /// use std::collections::HashSet;
180 /// let mut set = HashSet::new();
181 /// set.insert("a");
182 /// set.insert("b");
183 ///
184 /// // Will print in an arbitrary order.
185 /// for x in set.iter() {
5e7ed085 186 /// println!("{x}");
9fa01778
XL
187 /// }
188 /// ```
923072b8
FG
189 ///
190 /// # Performance
191 ///
192 /// In the current implementation, iterating over set takes O(capacity) time
193 /// instead of O(len) because it internally visits empty buckets too.
48663c56 194 #[inline]
5e7ed085 195 #[rustc_lint_query_instability]
9fa01778 196 #[stable(feature = "rust1", since = "1.0.0")]
532ac7d7 197 pub fn iter(&self) -> Iter<'_, T> {
1b1a35ee 198 Iter { base: self.base.iter() }
9fa01778
XL
199 }
200
201 /// Returns the number of elements in the set.
202 ///
203 /// # Examples
204 ///
205 /// ```
206 /// use std::collections::HashSet;
207 ///
208 /// let mut v = HashSet::new();
209 /// assert_eq!(v.len(), 0);
210 /// v.insert(1);
211 /// assert_eq!(v.len(), 1);
212 /// ```
48663c56 213 #[inline]
9fa01778
XL
214 #[stable(feature = "rust1", since = "1.0.0")]
215 pub fn len(&self) -> usize {
1b1a35ee 216 self.base.len()
9fa01778
XL
217 }
218
219 /// Returns `true` if the set contains no elements.
220 ///
221 /// # Examples
222 ///
223 /// ```
224 /// use std::collections::HashSet;
225 ///
226 /// let mut v = HashSet::new();
227 /// assert!(v.is_empty());
228 /// v.insert(1);
229 /// assert!(!v.is_empty());
230 /// ```
48663c56 231 #[inline]
9fa01778
XL
232 #[stable(feature = "rust1", since = "1.0.0")]
233 pub fn is_empty(&self) -> bool {
1b1a35ee 234 self.base.is_empty()
9fa01778
XL
235 }
236
5099ac24
FG
237 /// Clears the set, returning all elements as an iterator. Keeps the
238 /// allocated memory for reuse.
239 ///
240 /// If the returned iterator is dropped before being fully consumed, it
241 /// drops the remaining elements. The returned iterator keeps a mutable
242 /// borrow on the vector to optimize its implementation.
9fa01778
XL
243 ///
244 /// # Examples
245 ///
246 /// ```
247 /// use std::collections::HashSet;
248 ///
a2a8927a 249 /// let mut set = HashSet::from([1, 2, 3]);
9fa01778
XL
250 /// assert!(!set.is_empty());
251 ///
252 /// // print 1, 2, 3 in an arbitrary order
253 /// for i in set.drain() {
5e7ed085 254 /// println!("{i}");
9fa01778
XL
255 /// }
256 ///
257 /// assert!(set.is_empty());
258 /// ```
259 #[inline]
5e7ed085 260 #[rustc_lint_query_instability]
9fa01778 261 #[stable(feature = "drain", since = "1.6.0")]
532ac7d7 262 pub fn drain(&mut self) -> Drain<'_, T> {
1b1a35ee
XL
263 Drain { base: self.base.drain() }
264 }
265
266 /// Creates an iterator which uses a closure to determine if a value should be removed.
267 ///
268 /// If the closure returns true, then the value is removed and yielded.
269 /// If the closure returns false, the value will remain in the list and will not be yielded
270 /// by the iterator.
271 ///
272 /// If the iterator is only partially consumed or not consumed at all, each of the remaining
273 /// values will still be subjected to the closure and removed and dropped if it returns true.
274 ///
275 /// It is unspecified how many more values will be subjected to the closure
276 /// if a panic occurs in the closure, or if a panic occurs while dropping a value, or if the
277 /// `DrainFilter` itself is leaked.
278 ///
279 /// # Examples
280 ///
281 /// Splitting a set into even and odd values, reusing the original set:
282 ///
283 /// ```
284 /// #![feature(hash_drain_filter)]
285 /// use std::collections::HashSet;
286 ///
287 /// let mut set: HashSet<i32> = (0..8).collect();
288 /// let drained: HashSet<i32> = set.drain_filter(|v| v % 2 == 0).collect();
289 ///
290 /// let mut evens = drained.into_iter().collect::<Vec<_>>();
291 /// let mut odds = set.into_iter().collect::<Vec<_>>();
292 /// evens.sort();
293 /// odds.sort();
294 ///
295 /// assert_eq!(evens, vec![0, 2, 4, 6]);
296 /// assert_eq!(odds, vec![1, 3, 5, 7]);
297 /// ```
298 #[inline]
5e7ed085 299 #[rustc_lint_query_instability]
1b1a35ee
XL
300 #[unstable(feature = "hash_drain_filter", issue = "59618")]
301 pub fn drain_filter<F>(&mut self, pred: F) -> DrainFilter<'_, T, F>
302 where
303 F: FnMut(&T) -> bool,
304 {
305 DrainFilter { base: self.base.drain_filter(pred) }
9fa01778
XL
306 }
307
a2a8927a
XL
308 /// Retains only the elements specified by the predicate.
309 ///
5e7ed085 310 /// In other words, remove all elements `e` for which `f(&e)` returns `false`.
a2a8927a
XL
311 /// The elements are visited in unsorted (and unspecified) order.
312 ///
313 /// # Examples
314 ///
315 /// ```
316 /// use std::collections::HashSet;
317 ///
318 /// let mut set = HashSet::from([1, 2, 3, 4, 5, 6]);
319 /// set.retain(|&k| k % 2 == 0);
320 /// assert_eq!(set.len(), 3);
321 /// ```
923072b8
FG
322 ///
323 /// # Performance
324 ///
325 /// In the current implementation, this operation takes O(capacity) time
326 /// instead of O(len) because it internally visits empty buckets too.
5e7ed085 327 #[rustc_lint_query_instability]
a2a8927a
XL
328 #[stable(feature = "retain_hash_collection", since = "1.18.0")]
329 pub fn retain<F>(&mut self, f: F)
330 where
331 F: FnMut(&T) -> bool,
332 {
333 self.base.retain(f)
334 }
335
9fa01778
XL
336 /// Clears the set, removing all values.
337 ///
338 /// # Examples
339 ///
340 /// ```
341 /// use std::collections::HashSet;
342 ///
343 /// let mut v = HashSet::new();
344 /// v.insert(1);
345 /// v.clear();
346 /// assert!(v.is_empty());
347 /// ```
48663c56 348 #[inline]
9fa01778
XL
349 #[stable(feature = "rust1", since = "1.0.0")]
350 pub fn clear(&mut self) {
1b1a35ee 351 self.base.clear()
9fa01778 352 }
9fa01778 353
1a4d82fc
JJ
354 /// Creates a new empty hash set which will use the given hasher to hash
355 /// keys.
356 ///
357 /// The hash set is also created with the default initial capacity.
358 ///
9cc50fc6
SL
359 /// Warning: `hasher` is normally randomly generated, and
360 /// is designed to allow `HashSet`s to be resistant to attacks that
361 /// cause many collisions and very poor performance. Setting it
362 /// manually using this function can expose a DoS attack vector.
363 ///
f9f354fc
XL
364 /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
365 /// the HashMap to be useful, see its documentation for details.
366 ///
c34b1796 367 /// # Examples
1a4d82fc
JJ
368 ///
369 /// ```
370 /// use std::collections::HashSet;
371 /// use std::collections::hash_map::RandomState;
372 ///
373 /// let s = RandomState::new();
9cc50fc6 374 /// let mut set = HashSet::with_hasher(s);
85aaf69f 375 /// set.insert(2);
1a4d82fc
JJ
376 /// ```
377 #[inline]
9cc50fc6
SL
378 #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
379 pub fn with_hasher(hasher: S) -> HashSet<T, S> {
1b1a35ee 380 HashSet { base: base::HashSet::with_hasher(hasher) }
1a4d82fc
JJ
381 }
382
923072b8 383 /// Creates an empty `HashSet` with at least the specified capacity, using
c30ab7b3
SL
384 /// `hasher` to hash the keys.
385 ///
386 /// The hash set will be able to hold at least `capacity` elements without
923072b8
FG
387 /// reallocating. This method is allowed to allocate for more elements than
388 /// `capacity`. If `capacity` is 0, the hash set will not allocate.
1a4d82fc
JJ
389 ///
390 /// Warning: `hasher` is normally randomly generated, and
391 /// is designed to allow `HashSet`s to be resistant to attacks that
392 /// cause many collisions and very poor performance. Setting it
393 /// manually using this function can expose a DoS attack vector.
394 ///
f9f354fc
XL
395 /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
396 /// the HashMap to be useful, see its documentation for details.
397 ///
c34b1796 398 /// # Examples
1a4d82fc
JJ
399 ///
400 /// ```
401 /// use std::collections::HashSet;
402 /// use std::collections::hash_map::RandomState;
403 ///
404 /// let s = RandomState::new();
9cc50fc6 405 /// let mut set = HashSet::with_capacity_and_hasher(10, s);
85aaf69f 406 /// set.insert(1);
1a4d82fc
JJ
407 /// ```
408 #[inline]
9cc50fc6 409 #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
c30ab7b3 410 pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet<T, S> {
1b1a35ee 411 HashSet { base: base::HashSet::with_capacity_and_hasher(capacity, hasher) }
9cc50fc6
SL
412 }
413
cc61c64b
XL
414 /// Returns a reference to the set's [`BuildHasher`].
415 ///
3b2f2976
XL
416 /// # Examples
417 ///
418 /// ```
419 /// use std::collections::HashSet;
420 /// use std::collections::hash_map::RandomState;
421 ///
422 /// let hasher = RandomState::new();
423 /// let set: HashSet<i32> = HashSet::with_hasher(hasher);
424 /// let hasher: &RandomState = set.hasher();
425 /// ```
48663c56 426 #[inline]
54a0048b 427 #[stable(feature = "hashmap_public_hasher", since = "1.9.0")]
7453a54e 428 pub fn hasher(&self) -> &S {
1b1a35ee 429 self.base.hasher()
7453a54e 430 }
74b04a01 431}
7453a54e 432
74b04a01
XL
433impl<T, S> HashSet<T, S>
434where
435 T: Eq + Hash,
436 S: BuildHasher,
437{
1a4d82fc 438 /// Reserves capacity for at least `additional` more elements to be inserted
923072b8
FG
439 /// in the `HashSet`. The collection may reserve more space to speculatively
440 /// avoid frequent reallocations. After calling `reserve`,
441 /// capacity will be greater than or equal to `self.len() + additional`.
442 /// Does nothing if capacity is already sufficient.
1a4d82fc
JJ
443 ///
444 /// # Panics
445 ///
85aaf69f 446 /// Panics if the new allocation size overflows `usize`.
1a4d82fc 447 ///
c34b1796 448 /// # Examples
1a4d82fc
JJ
449 ///
450 /// ```
451 /// use std::collections::HashSet;
85aaf69f 452 /// let mut set: HashSet<i32> = HashSet::new();
1a4d82fc 453 /// set.reserve(10);
3b2f2976 454 /// assert!(set.capacity() >= 10);
1a4d82fc 455 /// ```
48663c56 456 #[inline]
85aaf69f
SL
457 #[stable(feature = "rust1", since = "1.0.0")]
458 pub fn reserve(&mut self, additional: usize) {
1b1a35ee 459 self.base.reserve(additional)
1a4d82fc
JJ
460 }
461
48663c56 462 /// Tries to reserve capacity for at least `additional` more elements to be inserted
923072b8
FG
463 /// in the `HashSet`. The collection may reserve more space to speculatively
464 /// avoid frequent reallocations. After calling `reserve`,
465 /// capacity will be greater than or equal to `self.len() + additional` if
466 /// it returns `Ok(())`.
467 /// Does nothing if capacity is already sufficient.
48663c56
XL
468 ///
469 /// # Errors
470 ///
471 /// If the capacity overflows, or the allocator reports a failure, then an error
472 /// is returned.
473 ///
474 /// # Examples
475 ///
476 /// ```
48663c56
XL
477 /// use std::collections::HashSet;
478 /// let mut set: HashSet<i32> = HashSet::new();
923072b8 479 /// set.try_reserve(10).expect("why is the test harness OOMing on a handful of bytes?");
48663c56
XL
480 /// ```
481 #[inline]
c295e0f8 482 #[stable(feature = "try_reserve", since = "1.57.0")]
e1599b0c 483 pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
1b1a35ee 484 self.base.try_reserve(additional).map_err(map_try_reserve_error)
48663c56
XL
485 }
486
1a4d82fc
JJ
487 /// Shrinks the capacity of the set as much as possible. It will drop
488 /// down as much as possible while maintaining the internal rules
489 /// and possibly leaving some space in accordance with the resize policy.
490 ///
c34b1796 491 /// # Examples
1a4d82fc
JJ
492 ///
493 /// ```
494 /// use std::collections::HashSet;
495 ///
85aaf69f 496 /// let mut set = HashSet::with_capacity(100);
1a4d82fc
JJ
497 /// set.insert(1);
498 /// set.insert(2);
499 /// assert!(set.capacity() >= 100);
500 /// set.shrink_to_fit();
501 /// assert!(set.capacity() >= 2);
502 /// ```
48663c56 503 #[inline]
85aaf69f 504 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 505 pub fn shrink_to_fit(&mut self) {
1b1a35ee 506 self.base.shrink_to_fit()
1a4d82fc
JJ
507 }
508
0531ce1d
XL
509 /// Shrinks the capacity of the set with a lower limit. It will drop
510 /// down no lower than the supplied limit while maintaining the internal rules
511 /// and possibly leaving some space in accordance with the resize policy.
512 ///
5869c6ff 513 /// If the current capacity is less than the lower limit, this is a no-op.
0531ce1d
XL
514 /// # Examples
515 ///
516 /// ```
0531ce1d
XL
517 /// use std::collections::HashSet;
518 ///
519 /// let mut set = HashSet::with_capacity(100);
520 /// set.insert(1);
521 /// set.insert(2);
522 /// assert!(set.capacity() >= 100);
523 /// set.shrink_to(10);
524 /// assert!(set.capacity() >= 10);
525 /// set.shrink_to(0);
526 /// assert!(set.capacity() >= 2);
527 /// ```
528 #[inline]
94222f64 529 #[stable(feature = "shrink_to", since = "1.56.0")]
0531ce1d 530 pub fn shrink_to(&mut self, min_capacity: usize) {
1b1a35ee 531 self.base.shrink_to(min_capacity)
0531ce1d
XL
532 }
533
cc61c64b 534 /// Visits the values representing the difference,
0731742a 535 /// i.e., the values that are in `self` but not in `other`.
1a4d82fc 536 ///
c34b1796 537 /// # Examples
1a4d82fc
JJ
538 ///
539 /// ```
540 /// use std::collections::HashSet;
a2a8927a
XL
541 /// let a = HashSet::from([1, 2, 3]);
542 /// let b = HashSet::from([4, 2, 3, 4]);
1a4d82fc
JJ
543 ///
544 /// // Can be seen as `a - b`.
545 /// for x in a.difference(&b) {
5e7ed085 546 /// println!("{x}"); // Print 1
1a4d82fc
JJ
547 /// }
548 ///
3b2f2976
XL
549 /// let diff: HashSet<_> = a.difference(&b).collect();
550 /// assert_eq!(diff, [1].iter().collect());
1a4d82fc
JJ
551 ///
552 /// // Note that difference is not symmetric,
553 /// // and `b - a` means something else:
3b2f2976
XL
554 /// let diff: HashSet<_> = b.difference(&a).collect();
555 /// assert_eq!(diff, [4].iter().collect());
1a4d82fc 556 /// ```
48663c56 557 #[inline]
5e7ed085 558 #[rustc_lint_query_instability]
85aaf69f 559 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 560 pub fn difference<'a>(&'a self, other: &'a HashSet<T, S>) -> Difference<'a, T, S> {
dfeec247 561 Difference { iter: self.iter(), other }
1a4d82fc
JJ
562 }
563
cc61c64b 564 /// Visits the values representing the symmetric difference,
0731742a 565 /// i.e., the values that are in `self` or in `other` but not in both.
1a4d82fc 566 ///
c34b1796 567 /// # Examples
1a4d82fc
JJ
568 ///
569 /// ```
570 /// use std::collections::HashSet;
a2a8927a
XL
571 /// let a = HashSet::from([1, 2, 3]);
572 /// let b = HashSet::from([4, 2, 3, 4]);
1a4d82fc
JJ
573 ///
574 /// // Print 1, 4 in arbitrary order.
575 /// for x in a.symmetric_difference(&b) {
5e7ed085 576 /// println!("{x}");
1a4d82fc
JJ
577 /// }
578 ///
3b2f2976
XL
579 /// let diff1: HashSet<_> = a.symmetric_difference(&b).collect();
580 /// let diff2: HashSet<_> = b.symmetric_difference(&a).collect();
1a4d82fc
JJ
581 ///
582 /// assert_eq!(diff1, diff2);
3b2f2976 583 /// assert_eq!(diff1, [1, 4].iter().collect());
1a4d82fc 584 /// ```
48663c56 585 #[inline]
5e7ed085 586 #[rustc_lint_query_instability]
85aaf69f 587 #[stable(feature = "rust1", since = "1.0.0")]
dfeec247
XL
588 pub fn symmetric_difference<'a>(
589 &'a self,
590 other: &'a HashSet<T, S>,
591 ) -> SymmetricDifference<'a, T, S> {
1a4d82fc
JJ
592 SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) }
593 }
594
cc61c64b 595 /// Visits the values representing the intersection,
0731742a 596 /// i.e., the values that are both in `self` and `other`.
1a4d82fc 597 ///
923072b8
FG
598 /// When an equal element is present in `self` and `other`
599 /// then the resulting `Intersection` may yield references to
600 /// one or the other. This can be relevant if `T` contains fields which
601 /// are not compared by its `Eq` implementation, and may hold different
602 /// value between the two equal copies of `T` in the two sets.
603 ///
c34b1796 604 /// # Examples
1a4d82fc
JJ
605 ///
606 /// ```
607 /// use std::collections::HashSet;
a2a8927a
XL
608 /// let a = HashSet::from([1, 2, 3]);
609 /// let b = HashSet::from([4, 2, 3, 4]);
1a4d82fc
JJ
610 ///
611 /// // Print 2, 3 in arbitrary order.
612 /// for x in a.intersection(&b) {
5e7ed085 613 /// println!("{x}");
1a4d82fc
JJ
614 /// }
615 ///
3b2f2976
XL
616 /// let intersection: HashSet<_> = a.intersection(&b).collect();
617 /// assert_eq!(intersection, [2, 3].iter().collect());
1a4d82fc 618 /// ```
48663c56 619 #[inline]
5e7ed085 620 #[rustc_lint_query_instability]
85aaf69f 621 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 622 pub fn intersection<'a>(&'a self, other: &'a HashSet<T, S>) -> Intersection<'a, T, S> {
0731742a 623 if self.len() <= other.len() {
dfeec247 624 Intersection { iter: self.iter(), other }
0731742a 625 } else {
dfeec247 626 Intersection { iter: other.iter(), other: self }
1a4d82fc
JJ
627 }
628 }
629
cc61c64b 630 /// Visits the values representing the union,
0731742a 631 /// i.e., all the values in `self` or `other`, without duplicates.
1a4d82fc 632 ///
c34b1796 633 /// # Examples
1a4d82fc
JJ
634 ///
635 /// ```
636 /// use std::collections::HashSet;
a2a8927a
XL
637 /// let a = HashSet::from([1, 2, 3]);
638 /// let b = HashSet::from([4, 2, 3, 4]);
1a4d82fc
JJ
639 ///
640 /// // Print 1, 2, 3, 4 in arbitrary order.
641 /// for x in a.union(&b) {
5e7ed085 642 /// println!("{x}");
1a4d82fc
JJ
643 /// }
644 ///
3b2f2976
XL
645 /// let union: HashSet<_> = a.union(&b).collect();
646 /// assert_eq!(union, [1, 2, 3, 4].iter().collect());
1a4d82fc 647 /// ```
48663c56 648 #[inline]
5e7ed085 649 #[rustc_lint_query_instability]
85aaf69f 650 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 651 pub fn union<'a>(&'a self, other: &'a HashSet<T, S>) -> Union<'a, T, S> {
60c5eb7d 652 if self.len() >= other.len() {
dfeec247 653 Union { iter: self.iter().chain(other.difference(self)) }
0731742a 654 } else {
dfeec247 655 Union { iter: other.iter().chain(self.difference(other)) }
0731742a 656 }
1a4d82fc
JJ
657 }
658
1a4d82fc
JJ
659 /// Returns `true` if the set contains a value.
660 ///
661 /// The value may be any borrowed form of the set's value type, but
cc61c64b 662 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1a4d82fc
JJ
663 /// the value type.
664 ///
c34b1796 665 /// # Examples
1a4d82fc
JJ
666 ///
667 /// ```
668 /// use std::collections::HashSet;
669 ///
a2a8927a 670 /// let set = HashSet::from([1, 2, 3]);
1a4d82fc
JJ
671 /// assert_eq!(set.contains(&1), true);
672 /// assert_eq!(set.contains(&4), false);
673 /// ```
48663c56 674 #[inline]
85aaf69f 675 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 676 pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
dfeec247
XL
677 where
678 T: Borrow<Q>,
679 Q: Hash + Eq,
1a4d82fc 680 {
1b1a35ee 681 self.base.contains(value)
1a4d82fc
JJ
682 }
683
e9174d1e
SL
684 /// Returns a reference to the value in the set, if any, that is equal to the given value.
685 ///
686 /// The value may be any borrowed form of the set's value type, but
cc61c64b 687 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
e9174d1e 688 /// the value type.
cc61c64b 689 ///
2c00a5a8
XL
690 /// # Examples
691 ///
692 /// ```
693 /// use std::collections::HashSet;
694 ///
a2a8927a 695 /// let set = HashSet::from([1, 2, 3]);
2c00a5a8
XL
696 /// assert_eq!(set.get(&2), Some(&2));
697 /// assert_eq!(set.get(&4), None);
698 /// ```
48663c56 699 #[inline]
54a0048b 700 #[stable(feature = "set_recovery", since = "1.9.0")]
e9174d1e 701 pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T>
dfeec247
XL
702 where
703 T: Borrow<Q>,
704 Q: Hash + Eq,
e9174d1e 705 {
1b1a35ee 706 self.base.get(value)
48663c56
XL
707 }
708
709 /// Inserts the given `value` into the set if it is not present, then
710 /// returns a reference to the value in the set.
711 ///
712 /// # Examples
713 ///
714 /// ```
715 /// #![feature(hash_set_entry)]
716 ///
717 /// use std::collections::HashSet;
718 ///
a2a8927a 719 /// let mut set = HashSet::from([1, 2, 3]);
48663c56
XL
720 /// assert_eq!(set.len(), 3);
721 /// assert_eq!(set.get_or_insert(2), &2);
722 /// assert_eq!(set.get_or_insert(100), &100);
723 /// assert_eq!(set.len(), 4); // 100 was inserted
724 /// ```
725 #[inline]
726 #[unstable(feature = "hash_set_entry", issue = "60896")]
727 pub fn get_or_insert(&mut self, value: T) -> &T {
728 // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with
729 // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`.
1b1a35ee 730 self.base.get_or_insert(value)
48663c56
XL
731 }
732
dfeec247
XL
733 /// Inserts an owned copy of the given `value` into the set if it is not
734 /// present, then returns a reference to the value in the set.
735 ///
736 /// # Examples
737 ///
738 /// ```
739 /// #![feature(hash_set_entry)]
740 ///
741 /// use std::collections::HashSet;
742 ///
743 /// let mut set: HashSet<String> = ["cat", "dog", "horse"]
744 /// .iter().map(|&pet| pet.to_owned()).collect();
745 ///
746 /// assert_eq!(set.len(), 3);
747 /// for &pet in &["cat", "dog", "fish"] {
748 /// let value = set.get_or_insert_owned(pet);
749 /// assert_eq!(value, pet);
750 /// }
751 /// assert_eq!(set.len(), 4); // a new "fish" was inserted
752 /// ```
753 #[inline]
754 #[unstable(feature = "hash_set_entry", issue = "60896")]
755 pub fn get_or_insert_owned<Q: ?Sized>(&mut self, value: &Q) -> &T
756 where
757 T: Borrow<Q>,
758 Q: Hash + Eq + ToOwned<Owned = T>,
759 {
760 // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with
761 // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`.
1b1a35ee 762 self.base.get_or_insert_owned(value)
dfeec247
XL
763 }
764
48663c56
XL
765 /// Inserts a value computed from `f` into the set if the given `value` is
766 /// not present, then returns a reference to the value in the set.
767 ///
768 /// # Examples
769 ///
770 /// ```
771 /// #![feature(hash_set_entry)]
772 ///
773 /// use std::collections::HashSet;
774 ///
775 /// let mut set: HashSet<String> = ["cat", "dog", "horse"]
776 /// .iter().map(|&pet| pet.to_owned()).collect();
777 ///
778 /// assert_eq!(set.len(), 3);
779 /// for &pet in &["cat", "dog", "fish"] {
780 /// let value = set.get_or_insert_with(pet, str::to_owned);
781 /// assert_eq!(value, pet);
782 /// }
783 /// assert_eq!(set.len(), 4); // a new "fish" was inserted
784 /// ```
785 #[inline]
786 #[unstable(feature = "hash_set_entry", issue = "60896")]
787 pub fn get_or_insert_with<Q: ?Sized, F>(&mut self, value: &Q, f: F) -> &T
dfeec247
XL
788 where
789 T: Borrow<Q>,
790 Q: Hash + Eq,
791 F: FnOnce(&Q) -> T,
48663c56
XL
792 {
793 // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with
794 // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`.
1b1a35ee 795 self.base.get_or_insert_with(value, f)
e9174d1e
SL
796 }
797
8bb4bdeb 798 /// Returns `true` if `self` has no elements in common with `other`.
1a4d82fc
JJ
799 /// This is equivalent to checking for an empty intersection.
800 ///
c34b1796 801 /// # Examples
1a4d82fc
JJ
802 ///
803 /// ```
804 /// use std::collections::HashSet;
805 ///
a2a8927a 806 /// let a = HashSet::from([1, 2, 3]);
85aaf69f 807 /// let mut b = HashSet::new();
1a4d82fc
JJ
808 ///
809 /// assert_eq!(a.is_disjoint(&b), true);
810 /// b.insert(4);
811 /// assert_eq!(a.is_disjoint(&b), true);
812 /// b.insert(1);
813 /// assert_eq!(a.is_disjoint(&b), false);
814 /// ```
85aaf69f 815 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 816 pub fn is_disjoint(&self, other: &HashSet<T, S>) -> bool {
0731742a
XL
817 if self.len() <= other.len() {
818 self.iter().all(|v| !other.contains(v))
819 } else {
820 other.iter().all(|v| !self.contains(v))
821 }
1a4d82fc
JJ
822 }
823
8bb4bdeb 824 /// Returns `true` if the set is a subset of another,
0731742a 825 /// i.e., `other` contains at least all the values in `self`.
1a4d82fc 826 ///
c34b1796 827 /// # Examples
1a4d82fc
JJ
828 ///
829 /// ```
830 /// use std::collections::HashSet;
831 ///
a2a8927a 832 /// let sup = HashSet::from([1, 2, 3]);
85aaf69f 833 /// let mut set = HashSet::new();
1a4d82fc
JJ
834 ///
835 /// assert_eq!(set.is_subset(&sup), true);
836 /// set.insert(2);
837 /// assert_eq!(set.is_subset(&sup), true);
838 /// set.insert(4);
839 /// assert_eq!(set.is_subset(&sup), false);
840 /// ```
85aaf69f 841 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 842 pub fn is_subset(&self, other: &HashSet<T, S>) -> bool {
dfeec247 843 if self.len() <= other.len() { self.iter().all(|v| other.contains(v)) } else { false }
1a4d82fc
JJ
844 }
845
8bb4bdeb 846 /// Returns `true` if the set is a superset of another,
0731742a 847 /// i.e., `self` contains at least all the values in `other`.
1a4d82fc 848 ///
c34b1796 849 /// # Examples
1a4d82fc
JJ
850 ///
851 /// ```
852 /// use std::collections::HashSet;
853 ///
a2a8927a 854 /// let sub = HashSet::from([1, 2]);
85aaf69f 855 /// let mut set = HashSet::new();
1a4d82fc
JJ
856 ///
857 /// assert_eq!(set.is_superset(&sub), false);
858 ///
859 /// set.insert(0);
860 /// set.insert(1);
861 /// assert_eq!(set.is_superset(&sub), false);
862 ///
863 /// set.insert(2);
864 /// assert_eq!(set.is_superset(&sub), true);
865 /// ```
866 #[inline]
85aaf69f 867 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
868 pub fn is_superset(&self, other: &HashSet<T, S>) -> bool {
869 other.is_subset(self)
870 }
871
b039eaaf
SL
872 /// Adds a value to the set.
873 ///
923072b8 874 /// Returns whether the value was newly inserted. That is:
b039eaaf 875 ///
923072b8
FG
876 /// - If the set did not previously contain this value, `true` is returned.
877 /// - If the set already contained this value, `false` is returned.
1a4d82fc 878 ///
c34b1796 879 /// # Examples
1a4d82fc
JJ
880 ///
881 /// ```
882 /// use std::collections::HashSet;
883 ///
884 /// let mut set = HashSet::new();
885 ///
85aaf69f 886 /// assert_eq!(set.insert(2), true);
1a4d82fc
JJ
887 /// assert_eq!(set.insert(2), false);
888 /// assert_eq!(set.len(), 1);
889 /// ```
48663c56 890 #[inline]
85aaf69f 891 #[stable(feature = "rust1", since = "1.0.0")]
c30ab7b3 892 pub fn insert(&mut self, value: T) -> bool {
1b1a35ee 893 self.base.insert(value)
c30ab7b3 894 }
1a4d82fc 895
e9174d1e
SL
896 /// Adds a value to the set, replacing the existing value, if any, that is equal to the given
897 /// one. Returns the replaced value.
2c00a5a8
XL
898 ///
899 /// # Examples
900 ///
901 /// ```
902 /// use std::collections::HashSet;
903 ///
904 /// let mut set = HashSet::new();
905 /// set.insert(Vec::<i32>::new());
906 ///
907 /// assert_eq!(set.get(&[][..]).unwrap().capacity(), 0);
908 /// set.replace(Vec::with_capacity(10));
909 /// assert_eq!(set.get(&[][..]).unwrap().capacity(), 10);
910 /// ```
48663c56 911 #[inline]
54a0048b 912 #[stable(feature = "set_recovery", since = "1.9.0")]
e9174d1e 913 pub fn replace(&mut self, value: T) -> Option<T> {
1b1a35ee 914 self.base.replace(value)
e9174d1e
SL
915 }
916
9fa01778 917 /// Removes a value from the set. Returns whether the value was
1a4d82fc
JJ
918 /// present in the set.
919 ///
920 /// The value may be any borrowed form of the set's value type, but
cc61c64b 921 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1a4d82fc
JJ
922 /// the value type.
923 ///
c34b1796 924 /// # Examples
1a4d82fc
JJ
925 ///
926 /// ```
927 /// use std::collections::HashSet;
928 ///
929 /// let mut set = HashSet::new();
930 ///
85aaf69f 931 /// set.insert(2);
1a4d82fc
JJ
932 /// assert_eq!(set.remove(&2), true);
933 /// assert_eq!(set.remove(&2), false);
934 /// ```
48663c56 935 #[inline]
85aaf69f 936 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 937 pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
dfeec247
XL
938 where
939 T: Borrow<Q>,
940 Q: Hash + Eq,
1a4d82fc 941 {
1b1a35ee 942 self.base.remove(value)
1a4d82fc 943 }
e9174d1e
SL
944
945 /// Removes and returns the value in the set, if any, that is equal to the given one.
946 ///
947 /// The value may be any borrowed form of the set's value type, but
cc61c64b 948 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
e9174d1e 949 /// the value type.
cc61c64b 950 ///
2c00a5a8
XL
951 /// # Examples
952 ///
953 /// ```
954 /// use std::collections::HashSet;
955 ///
a2a8927a 956 /// let mut set = HashSet::from([1, 2, 3]);
2c00a5a8
XL
957 /// assert_eq!(set.take(&2), Some(2));
958 /// assert_eq!(set.take(&2), None);
959 /// ```
48663c56 960 #[inline]
54a0048b 961 #[stable(feature = "set_recovery", since = "1.9.0")]
e9174d1e 962 pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T>
dfeec247
XL
963 where
964 T: Borrow<Q>,
965 Q: Hash + Eq,
e9174d1e 966 {
1b1a35ee 967 self.base.take(value)
e9174d1e 968 }
1a4d82fc
JJ
969}
970
5869c6ff
XL
971#[stable(feature = "rust1", since = "1.0.0")]
972impl<T, S> Clone for HashSet<T, S>
973where
974 T: Clone,
975 S: Clone,
976{
977 #[inline]
978 fn clone(&self) -> Self {
979 Self { base: self.base.clone() }
980 }
981
982 #[inline]
983 fn clone_from(&mut self, other: &Self) {
984 self.base.clone_from(&other.base);
985 }
986}
987
85aaf69f
SL
988#[stable(feature = "rust1", since = "1.0.0")]
989impl<T, S> PartialEq for HashSet<T, S>
dfeec247
XL
990where
991 T: Eq + Hash,
992 S: BuildHasher,
1a4d82fc
JJ
993{
994 fn eq(&self, other: &HashSet<T, S>) -> bool {
c30ab7b3
SL
995 if self.len() != other.len() {
996 return false;
997 }
1a4d82fc
JJ
998
999 self.iter().all(|key| other.contains(key))
1000 }
1001}
1002
85aaf69f
SL
1003#[stable(feature = "rust1", since = "1.0.0")]
1004impl<T, S> Eq for HashSet<T, S>
dfeec247
XL
1005where
1006 T: Eq + Hash,
1007 S: BuildHasher,
c30ab7b3
SL
1008{
1009}
1a4d82fc 1010
85aaf69f
SL
1011#[stable(feature = "rust1", since = "1.0.0")]
1012impl<T, S> fmt::Debug for HashSet<T, S>
dfeec247 1013where
74b04a01 1014 T: fmt::Debug,
1a4d82fc 1015{
532ac7d7 1016 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62682a34 1017 f.debug_set().entries(self.iter()).finish()
1a4d82fc
JJ
1018 }
1019}
1020
85aaf69f
SL
1021#[stable(feature = "rust1", since = "1.0.0")]
1022impl<T, S> FromIterator<T> for HashSet<T, S>
dfeec247
XL
1023where
1024 T: Eq + Hash,
1025 S: BuildHasher + Default,
1a4d82fc 1026{
48663c56 1027 #[inline]
c30ab7b3 1028 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> HashSet<T, S> {
476ff2be
SL
1029 let mut set = HashSet::with_hasher(Default::default());
1030 set.extend(iter);
1a4d82fc
JJ
1031 set
1032 }
1033}
1034
94222f64
XL
1035#[stable(feature = "std_collections_from_array", since = "1.56.0")]
1036// Note: as what is currently the most convenient built-in way to construct
1037// a HashSet, a simple usage of this function must not *require* the user
1038// to provide a type annotation in order to infer the third type parameter
1039// (the hasher parameter, conventionally "S").
1040// To that end, this impl is defined using RandomState as the concrete
1041// type of S, rather than being generic over `S: BuildHasher + Default`.
1042// It is expected that users who want to specify a hasher will manually use
1043// `with_capacity_and_hasher`.
1044// If type parameter defaults worked on impls, and if type parameter
1045// defaults could be mixed with const generics, then perhaps
1046// this could be generalized.
1047// See also the equivalent impl on HashMap.
1048impl<T, const N: usize> From<[T; N]> for HashSet<T, RandomState>
1049where
1050 T: Eq + Hash,
1051{
1052 /// # Examples
1053 ///
1054 /// ```
1055 /// use std::collections::HashSet;
1056 ///
1057 /// let set1 = HashSet::from([1, 2, 3, 4]);
1058 /// let set2: HashSet<_> = [1, 2, 3, 4].into();
1059 /// assert_eq!(set1, set2);
1060 /// ```
1061 fn from(arr: [T; N]) -> Self {
a2a8927a 1062 Self::from_iter(arr)
94222f64
XL
1063 }
1064}
1065
85aaf69f
SL
1066#[stable(feature = "rust1", since = "1.0.0")]
1067impl<T, S> Extend<T> for HashSet<T, S>
dfeec247
XL
1068where
1069 T: Eq + Hash,
1070 S: BuildHasher,
1a4d82fc 1071{
48663c56 1072 #[inline]
c30ab7b3 1073 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
1b1a35ee 1074 self.base.extend(iter);
1a4d82fc 1075 }
f9f354fc
XL
1076
1077 #[inline]
1078 fn extend_one(&mut self, item: T) {
1b1a35ee 1079 self.base.insert(item);
f9f354fc
XL
1080 }
1081
1082 #[inline]
1083 fn extend_reserve(&mut self, additional: usize) {
1b1a35ee 1084 self.base.extend_reserve(additional);
f9f354fc 1085 }
1a4d82fc
JJ
1086}
1087
e9174d1e
SL
1088#[stable(feature = "hash_extend_copy", since = "1.4.0")]
1089impl<'a, T, S> Extend<&'a T> for HashSet<T, S>
dfeec247
XL
1090where
1091 T: 'a + Eq + Hash + Copy,
1092 S: BuildHasher,
e9174d1e 1093{
48663c56 1094 #[inline]
c30ab7b3 1095 fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
e9174d1e
SL
1096 self.extend(iter.into_iter().cloned());
1097 }
f9f354fc
XL
1098
1099 #[inline]
1100 fn extend_one(&mut self, &item: &'a T) {
1b1a35ee 1101 self.base.insert(item);
f9f354fc
XL
1102 }
1103
1104 #[inline]
1105 fn extend_reserve(&mut self, additional: usize) {
1106 Extend::<T>::extend_reserve(self, additional)
1107 }
e9174d1e
SL
1108}
1109
85aaf69f
SL
1110#[stable(feature = "rust1", since = "1.0.0")]
1111impl<T, S> Default for HashSet<T, S>
dfeec247 1112where
74b04a01 1113 S: Default,
1a4d82fc 1114{
9e0c209e 1115 /// Creates an empty `HashSet<T, S>` with the `Default` value for the hasher.
48663c56 1116 #[inline]
1a4d82fc 1117 fn default() -> HashSet<T, S> {
1b1a35ee 1118 HashSet { base: Default::default() }
1a4d82fc
JJ
1119 }
1120}
1121
85aaf69f 1122#[stable(feature = "rust1", since = "1.0.0")]
532ac7d7 1123impl<T, S> BitOr<&HashSet<T, S>> for &HashSet<T, S>
dfeec247
XL
1124where
1125 T: Eq + Hash + Clone,
1126 S: BuildHasher + Default,
1a4d82fc
JJ
1127{
1128 type Output = HashSet<T, S>;
1129
1130 /// Returns the union of `self` and `rhs` as a new `HashSet<T, S>`.
1131 ///
1132 /// # Examples
1133 ///
1134 /// ```
1135 /// use std::collections::HashSet;
1136 ///
a2a8927a
XL
1137 /// let a = HashSet::from([1, 2, 3]);
1138 /// let b = HashSet::from([3, 4, 5]);
1a4d82fc 1139 ///
85aaf69f 1140 /// let set = &a | &b;
1a4d82fc
JJ
1141 ///
1142 /// let mut i = 0;
1143 /// let expected = [1, 2, 3, 4, 5];
62682a34 1144 /// for x in &set {
1a4d82fc
JJ
1145 /// assert!(expected.contains(x));
1146 /// i += 1;
1147 /// }
1148 /// assert_eq!(i, expected.len());
1149 /// ```
1150 fn bitor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
1151 self.union(rhs).cloned().collect()
1152 }
1153}
1154
85aaf69f 1155#[stable(feature = "rust1", since = "1.0.0")]
532ac7d7 1156impl<T, S> BitAnd<&HashSet<T, S>> for &HashSet<T, S>
dfeec247
XL
1157where
1158 T: Eq + Hash + Clone,
1159 S: BuildHasher + Default,
1a4d82fc
JJ
1160{
1161 type Output = HashSet<T, S>;
1162
1163 /// Returns the intersection of `self` and `rhs` as a new `HashSet<T, S>`.
1164 ///
1165 /// # Examples
1166 ///
1167 /// ```
1168 /// use std::collections::HashSet;
1169 ///
a2a8927a
XL
1170 /// let a = HashSet::from([1, 2, 3]);
1171 /// let b = HashSet::from([2, 3, 4]);
1a4d82fc 1172 ///
85aaf69f 1173 /// let set = &a & &b;
1a4d82fc
JJ
1174 ///
1175 /// let mut i = 0;
1176 /// let expected = [2, 3];
62682a34 1177 /// for x in &set {
1a4d82fc
JJ
1178 /// assert!(expected.contains(x));
1179 /// i += 1;
1180 /// }
1181 /// assert_eq!(i, expected.len());
1182 /// ```
1183 fn bitand(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
1184 self.intersection(rhs).cloned().collect()
1185 }
1186}
1187
85aaf69f 1188#[stable(feature = "rust1", since = "1.0.0")]
532ac7d7 1189impl<T, S> BitXor<&HashSet<T, S>> for &HashSet<T, S>
dfeec247
XL
1190where
1191 T: Eq + Hash + Clone,
1192 S: BuildHasher + Default,
1a4d82fc
JJ
1193{
1194 type Output = HashSet<T, S>;
1195
1196 /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet<T, S>`.
1197 ///
1198 /// # Examples
1199 ///
1200 /// ```
1201 /// use std::collections::HashSet;
1202 ///
a2a8927a
XL
1203 /// let a = HashSet::from([1, 2, 3]);
1204 /// let b = HashSet::from([3, 4, 5]);
1a4d82fc 1205 ///
85aaf69f 1206 /// let set = &a ^ &b;
1a4d82fc
JJ
1207 ///
1208 /// let mut i = 0;
1209 /// let expected = [1, 2, 4, 5];
62682a34 1210 /// for x in &set {
1a4d82fc
JJ
1211 /// assert!(expected.contains(x));
1212 /// i += 1;
1213 /// }
1214 /// assert_eq!(i, expected.len());
1215 /// ```
1216 fn bitxor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
1217 self.symmetric_difference(rhs).cloned().collect()
1218 }
1219}
1220
85aaf69f 1221#[stable(feature = "rust1", since = "1.0.0")]
532ac7d7 1222impl<T, S> Sub<&HashSet<T, S>> for &HashSet<T, S>
dfeec247
XL
1223where
1224 T: Eq + Hash + Clone,
1225 S: BuildHasher + Default,
1a4d82fc
JJ
1226{
1227 type Output = HashSet<T, S>;
1228
1229 /// Returns the difference of `self` and `rhs` as a new `HashSet<T, S>`.
1230 ///
1231 /// # Examples
1232 ///
1233 /// ```
1234 /// use std::collections::HashSet;
1235 ///
a2a8927a
XL
1236 /// let a = HashSet::from([1, 2, 3]);
1237 /// let b = HashSet::from([3, 4, 5]);
1a4d82fc 1238 ///
85aaf69f 1239 /// let set = &a - &b;
1a4d82fc
JJ
1240 ///
1241 /// let mut i = 0;
1242 /// let expected = [1, 2];
62682a34 1243 /// for x in &set {
1a4d82fc
JJ
1244 /// assert!(expected.contains(x));
1245 /// i += 1;
1246 /// }
1247 /// assert_eq!(i, expected.len());
1248 /// ```
1249 fn sub(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
1250 self.difference(rhs).cloned().collect()
1251 }
1252}
1253
cc61c64b
XL
1254/// An iterator over the items of a `HashSet`.
1255///
1256/// This `struct` is created by the [`iter`] method on [`HashSet`].
1257/// See its documentation for more.
1258///
3dfed10e 1259/// [`iter`]: HashSet::iter
1b1a35ee
XL
1260///
1261/// # Examples
1262///
1263/// ```
1264/// use std::collections::HashSet;
1265///
a2a8927a 1266/// let a = HashSet::from([1, 2, 3]);
1b1a35ee
XL
1267///
1268/// let mut iter = a.iter();
1269/// ```
85aaf69f 1270#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 1271pub struct Iter<'a, K: 'a> {
1b1a35ee 1272 base: base::Iter<'a, K>,
1a4d82fc
JJ
1273}
1274
cc61c64b
XL
1275/// An owning iterator over the items of a `HashSet`.
1276///
dfeec247 1277/// This `struct` is created by the [`into_iter`] method on [`HashSet`]
c295e0f8 1278/// (provided by the [`IntoIterator`] trait). See its documentation for more.
cc61c64b 1279///
3dfed10e 1280/// [`into_iter`]: IntoIterator::into_iter
c295e0f8 1281/// [`IntoIterator`]: crate::iter::IntoIterator
1b1a35ee
XL
1282///
1283/// # Examples
1284///
1285/// ```
1286/// use std::collections::HashSet;
1287///
a2a8927a 1288/// let a = HashSet::from([1, 2, 3]);
1b1a35ee
XL
1289///
1290/// let mut iter = a.into_iter();
1291/// ```
85aaf69f 1292#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 1293pub struct IntoIter<K> {
1b1a35ee 1294 base: base::IntoIter<K>,
1a4d82fc
JJ
1295}
1296
cc61c64b
XL
1297/// A draining iterator over the items of a `HashSet`.
1298///
1299/// This `struct` is created by the [`drain`] method on [`HashSet`].
1300/// See its documentation for more.
1301///
3dfed10e 1302/// [`drain`]: HashSet::drain
1b1a35ee
XL
1303///
1304/// # Examples
1305///
1306/// ```
1307/// use std::collections::HashSet;
1308///
a2a8927a 1309/// let mut a = HashSet::from([1, 2, 3]);
1b1a35ee
XL
1310///
1311/// let mut drain = a.drain();
1312/// ```
85aaf69f 1313#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 1314pub struct Drain<'a, K: 'a> {
1b1a35ee
XL
1315 base: base::Drain<'a, K>,
1316}
1317
1318/// A draining, filtering iterator over the items of a `HashSet`.
1319///
1320/// This `struct` is created by the [`drain_filter`] method on [`HashSet`].
1321///
1322/// [`drain_filter`]: HashSet::drain_filter
1323///
1324/// # Examples
1325///
1326/// ```
1327/// #![feature(hash_drain_filter)]
1328///
1329/// use std::collections::HashSet;
1330///
a2a8927a 1331/// let mut a = HashSet::from([1, 2, 3]);
1b1a35ee
XL
1332///
1333/// let mut drain_filtered = a.drain_filter(|v| v % 2 == 0);
1334/// ```
1335#[unstable(feature = "hash_drain_filter", issue = "59618")]
1336pub struct DrainFilter<'a, K, F>
1337where
1338 F: FnMut(&K) -> bool,
1339{
1340 base: base::DrainFilter<'a, K, F>,
1a4d82fc
JJ
1341}
1342
cc61c64b
XL
1343/// A lazy iterator producing elements in the intersection of `HashSet`s.
1344///
1345/// This `struct` is created by the [`intersection`] method on [`HashSet`].
1346/// See its documentation for more.
1347///
3dfed10e 1348/// [`intersection`]: HashSet::intersection
1b1a35ee
XL
1349///
1350/// # Examples
1351///
1352/// ```
1353/// use std::collections::HashSet;
1354///
a2a8927a
XL
1355/// let a = HashSet::from([1, 2, 3]);
1356/// let b = HashSet::from([4, 2, 3, 4]);
1b1a35ee
XL
1357///
1358/// let mut intersection = a.intersection(&b);
1359/// ```
3c0e092e
XL
1360#[must_use = "this returns the intersection as an iterator, \
1361 without modifying either input set"]
85aaf69f 1362#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
1363pub struct Intersection<'a, T: 'a, S: 'a> {
1364 // iterator of the first set
1365 iter: Iter<'a, T>,
1366 // the second set
1367 other: &'a HashSet<T, S>,
1368}
1369
cc61c64b
XL
1370/// A lazy iterator producing elements in the difference of `HashSet`s.
1371///
1372/// This `struct` is created by the [`difference`] method on [`HashSet`].
1373/// See its documentation for more.
1374///
3dfed10e 1375/// [`difference`]: HashSet::difference
1b1a35ee
XL
1376///
1377/// # Examples
1378///
1379/// ```
1380/// use std::collections::HashSet;
1381///
a2a8927a
XL
1382/// let a = HashSet::from([1, 2, 3]);
1383/// let b = HashSet::from([4, 2, 3, 4]);
1b1a35ee
XL
1384///
1385/// let mut difference = a.difference(&b);
1386/// ```
3c0e092e
XL
1387#[must_use = "this returns the difference as an iterator, \
1388 without modifying either input set"]
85aaf69f 1389#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
1390pub struct Difference<'a, T: 'a, S: 'a> {
1391 // iterator of the first set
1392 iter: Iter<'a, T>,
1393 // the second set
1394 other: &'a HashSet<T, S>,
1395}
1396
cc61c64b
XL
1397/// A lazy iterator producing elements in the symmetric difference of `HashSet`s.
1398///
1399/// This `struct` is created by the [`symmetric_difference`] method on
1400/// [`HashSet`]. See its documentation for more.
1401///
3dfed10e 1402/// [`symmetric_difference`]: HashSet::symmetric_difference
1b1a35ee
XL
1403///
1404/// # Examples
1405///
1406/// ```
1407/// use std::collections::HashSet;
1408///
a2a8927a
XL
1409/// let a = HashSet::from([1, 2, 3]);
1410/// let b = HashSet::from([4, 2, 3, 4]);
1b1a35ee
XL
1411///
1412/// let mut intersection = a.symmetric_difference(&b);
1413/// ```
3c0e092e
XL
1414#[must_use = "this returns the difference as an iterator, \
1415 without modifying either input set"]
85aaf69f 1416#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 1417pub struct SymmetricDifference<'a, T: 'a, S: 'a> {
c30ab7b3 1418 iter: Chain<Difference<'a, T, S>, Difference<'a, T, S>>,
1a4d82fc
JJ
1419}
1420
cc61c64b
XL
1421/// A lazy iterator producing elements in the union of `HashSet`s.
1422///
1423/// This `struct` is created by the [`union`] method on [`HashSet`].
1424/// See its documentation for more.
1425///
3dfed10e 1426/// [`union`]: HashSet::union
1b1a35ee
XL
1427///
1428/// # Examples
1429///
1430/// ```
1431/// use std::collections::HashSet;
1432///
a2a8927a
XL
1433/// let a = HashSet::from([1, 2, 3]);
1434/// let b = HashSet::from([4, 2, 3, 4]);
1b1a35ee
XL
1435///
1436/// let mut union_iter = a.union(&b);
1437/// ```
3c0e092e
XL
1438#[must_use = "this returns the union as an iterator, \
1439 without modifying either input set"]
85aaf69f 1440#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 1441pub struct Union<'a, T: 'a, S: 'a> {
c30ab7b3 1442 iter: Chain<Iter<'a, T>, Difference<'a, T, S>>,
1a4d82fc
JJ
1443}
1444
85aaf69f 1445#[stable(feature = "rust1", since = "1.0.0")]
9fa01778 1446impl<'a, T, S> IntoIterator for &'a HashSet<T, S> {
85aaf69f
SL
1447 type Item = &'a T;
1448 type IntoIter = Iter<'a, T>;
1449
48663c56 1450 #[inline]
5e7ed085 1451 #[rustc_lint_query_instability]
85aaf69f
SL
1452 fn into_iter(self) -> Iter<'a, T> {
1453 self.iter()
1454 }
1455}
1456
1457#[stable(feature = "rust1", since = "1.0.0")]
9fa01778 1458impl<T, S> IntoIterator for HashSet<T, S> {
85aaf69f
SL
1459 type Item = T;
1460 type IntoIter = IntoIter<T>;
1461
9346a6ac
AL
1462 /// Creates a consuming iterator, that is, one that moves each value out
1463 /// of the set in arbitrary order. The set cannot be used after calling
1464 /// this.
1465 ///
1466 /// # Examples
1467 ///
1468 /// ```
1469 /// use std::collections::HashSet;
1470 /// let mut set = HashSet::new();
1471 /// set.insert("a".to_string());
1472 /// set.insert("b".to_string());
1473 ///
1474 /// // Not possible to collect to a Vec<String> with a regular `.iter()`.
1475 /// let v: Vec<String> = set.into_iter().collect();
1476 ///
1477 /// // Will print in an arbitrary order.
62682a34 1478 /// for x in &v {
5e7ed085 1479 /// println!("{x}");
9346a6ac
AL
1480 /// }
1481 /// ```
48663c56 1482 #[inline]
5e7ed085 1483 #[rustc_lint_query_instability]
85aaf69f 1484 fn into_iter(self) -> IntoIter<T> {
1b1a35ee 1485 IntoIter { base: self.base.into_iter() }
85aaf69f
SL
1486 }
1487}
1488
92a42be0 1489#[stable(feature = "rust1", since = "1.0.0")]
9fa01778 1490impl<K> Clone for Iter<'_, K> {
48663c56 1491 #[inline]
9fa01778 1492 fn clone(&self) -> Self {
1b1a35ee 1493 Iter { base: self.base.clone() }
c30ab7b3 1494 }
c34b1796 1495}
85aaf69f 1496#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
1497impl<'a, K> Iterator for Iter<'a, K> {
1498 type Item = &'a K;
1499
48663c56 1500 #[inline]
c30ab7b3 1501 fn next(&mut self) -> Option<&'a K> {
1b1a35ee 1502 self.base.next()
c30ab7b3 1503 }
48663c56 1504 #[inline]
c30ab7b3 1505 fn size_hint(&self) -> (usize, Option<usize>) {
1b1a35ee 1506 self.base.size_hint()
c30ab7b3 1507 }
85aaf69f
SL
1508}
1509#[stable(feature = "rust1", since = "1.0.0")]
9fa01778 1510impl<K> ExactSizeIterator for Iter<'_, K> {
48663c56 1511 #[inline]
c30ab7b3 1512 fn len(&self) -> usize {
1b1a35ee 1513 self.base.len()
c30ab7b3 1514 }
1a4d82fc 1515}
0531ce1d 1516#[stable(feature = "fused", since = "1.26.0")]
9fa01778 1517impl<K> FusedIterator for Iter<'_, K> {}
1a4d82fc 1518
8bb4bdeb 1519#[stable(feature = "std_debug", since = "1.16.0")]
9fa01778 1520impl<K: fmt::Debug> fmt::Debug for Iter<'_, K> {
532ac7d7 1521 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
cc61c64b 1522 f.debug_list().entries(self.clone()).finish()
32a655c1
SL
1523 }
1524}
1525
85aaf69f 1526#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
1527impl<K> Iterator for IntoIter<K> {
1528 type Item = K;
1529
48663c56 1530 #[inline]
c30ab7b3 1531 fn next(&mut self) -> Option<K> {
1b1a35ee 1532 self.base.next()
c30ab7b3 1533 }
48663c56 1534 #[inline]
c30ab7b3 1535 fn size_hint(&self) -> (usize, Option<usize>) {
1b1a35ee 1536 self.base.size_hint()
c30ab7b3 1537 }
85aaf69f
SL
1538}
1539#[stable(feature = "rust1", since = "1.0.0")]
1540impl<K> ExactSizeIterator for IntoIter<K> {
48663c56 1541 #[inline]
c30ab7b3 1542 fn len(&self) -> usize {
1b1a35ee 1543 self.base.len()
c30ab7b3 1544 }
1a4d82fc 1545}
0531ce1d 1546#[stable(feature = "fused", since = "1.26.0")]
9e0c209e 1547impl<K> FusedIterator for IntoIter<K> {}
1a4d82fc 1548
8bb4bdeb 1549#[stable(feature = "std_debug", since = "1.16.0")]
32a655c1 1550impl<K: fmt::Debug> fmt::Debug for IntoIter<K> {
532ac7d7 1551 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1b1a35ee 1552 fmt::Debug::fmt(&self.base, f)
32a655c1
SL
1553 }
1554}
1555
85aaf69f
SL
1556#[stable(feature = "rust1", since = "1.0.0")]
1557impl<'a, K> Iterator for Drain<'a, K> {
1a4d82fc
JJ
1558 type Item = K;
1559
48663c56 1560 #[inline]
c30ab7b3 1561 fn next(&mut self) -> Option<K> {
1b1a35ee 1562 self.base.next()
c30ab7b3 1563 }
48663c56 1564 #[inline]
c30ab7b3 1565 fn size_hint(&self) -> (usize, Option<usize>) {
1b1a35ee 1566 self.base.size_hint()
c30ab7b3 1567 }
85aaf69f
SL
1568}
1569#[stable(feature = "rust1", since = "1.0.0")]
9fa01778 1570impl<K> ExactSizeIterator for Drain<'_, K> {
48663c56 1571 #[inline]
c30ab7b3 1572 fn len(&self) -> usize {
1b1a35ee 1573 self.base.len()
c30ab7b3 1574 }
1a4d82fc 1575}
0531ce1d 1576#[stable(feature = "fused", since = "1.26.0")]
9fa01778 1577impl<K> FusedIterator for Drain<'_, K> {}
1a4d82fc 1578
8bb4bdeb 1579#[stable(feature = "std_debug", since = "1.16.0")]
9fa01778 1580impl<K: fmt::Debug> fmt::Debug for Drain<'_, K> {
532ac7d7 1581 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1b1a35ee
XL
1582 fmt::Debug::fmt(&self.base, f)
1583 }
1584}
1585
1586#[unstable(feature = "hash_drain_filter", issue = "59618")]
1587impl<K, F> Iterator for DrainFilter<'_, K, F>
1588where
1589 F: FnMut(&K) -> bool,
1590{
1591 type Item = K;
1592
1593 #[inline]
1594 fn next(&mut self) -> Option<K> {
1595 self.base.next()
1596 }
1597 #[inline]
1598 fn size_hint(&self) -> (usize, Option<usize>) {
1599 self.base.size_hint()
1600 }
1601}
1602
1603#[unstable(feature = "hash_drain_filter", issue = "59618")]
1604impl<K, F> FusedIterator for DrainFilter<'_, K, F> where F: FnMut(&K) -> bool {}
1605
1606#[unstable(feature = "hash_drain_filter", issue = "59618")]
1607impl<'a, K, F> fmt::Debug for DrainFilter<'a, K, F>
1608where
1609 F: FnMut(&K) -> bool,
1610{
1611 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
cdc7bbd5 1612 f.debug_struct("DrainFilter").finish_non_exhaustive()
32a655c1
SL
1613 }
1614}
1615
92a42be0 1616#[stable(feature = "rust1", since = "1.0.0")]
9fa01778 1617impl<T, S> Clone for Intersection<'_, T, S> {
48663c56 1618 #[inline]
9fa01778 1619 fn clone(&self) -> Self {
c34b1796
AL
1620 Intersection { iter: self.iter.clone(), ..*self }
1621 }
1622}
1623
85aaf69f
SL
1624#[stable(feature = "rust1", since = "1.0.0")]
1625impl<'a, T, S> Iterator for Intersection<'a, T, S>
dfeec247
XL
1626where
1627 T: Eq + Hash,
1628 S: BuildHasher,
1a4d82fc
JJ
1629{
1630 type Item = &'a T;
1631
48663c56 1632 #[inline]
1a4d82fc
JJ
1633 fn next(&mut self) -> Option<&'a T> {
1634 loop {
ff7c6d11
XL
1635 let elt = self.iter.next()?;
1636 if self.other.contains(elt) {
1637 return Some(elt);
1a4d82fc
JJ
1638 }
1639 }
1640 }
1641
48663c56 1642 #[inline]
85aaf69f 1643 fn size_hint(&self) -> (usize, Option<usize>) {
1a4d82fc
JJ
1644 let (_, upper) = self.iter.size_hint();
1645 (0, upper)
1646 }
1647}
1648
8bb4bdeb 1649#[stable(feature = "std_debug", since = "1.16.0")]
9fa01778 1650impl<T, S> fmt::Debug for Intersection<'_, T, S>
dfeec247
XL
1651where
1652 T: fmt::Debug + Eq + Hash,
1653 S: BuildHasher,
32a655c1 1654{
532ac7d7 1655 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
cc61c64b 1656 f.debug_list().entries(self.clone()).finish()
32a655c1
SL
1657 }
1658}
1659
0531ce1d 1660#[stable(feature = "fused", since = "1.26.0")]
9fa01778 1661impl<T, S> FusedIterator for Intersection<'_, T, S>
dfeec247
XL
1662where
1663 T: Eq + Hash,
1664 S: BuildHasher,
c30ab7b3
SL
1665{
1666}
9e0c209e 1667
92a42be0 1668#[stable(feature = "rust1", since = "1.0.0")]
9fa01778 1669impl<T, S> Clone for Difference<'_, T, S> {
48663c56 1670 #[inline]
9fa01778 1671 fn clone(&self) -> Self {
c34b1796
AL
1672 Difference { iter: self.iter.clone(), ..*self }
1673 }
1674}
1675
85aaf69f
SL
1676#[stable(feature = "rust1", since = "1.0.0")]
1677impl<'a, T, S> Iterator for Difference<'a, T, S>
dfeec247
XL
1678where
1679 T: Eq + Hash,
1680 S: BuildHasher,
1a4d82fc
JJ
1681{
1682 type Item = &'a T;
1683
48663c56 1684 #[inline]
1a4d82fc
JJ
1685 fn next(&mut self) -> Option<&'a T> {
1686 loop {
ff7c6d11
XL
1687 let elt = self.iter.next()?;
1688 if !self.other.contains(elt) {
1689 return Some(elt);
1a4d82fc
JJ
1690 }
1691 }
1692 }
1693
48663c56 1694 #[inline]
85aaf69f 1695 fn size_hint(&self) -> (usize, Option<usize>) {
1a4d82fc
JJ
1696 let (_, upper) = self.iter.size_hint();
1697 (0, upper)
1698 }
1699}
1700
0531ce1d 1701#[stable(feature = "fused", since = "1.26.0")]
9fa01778 1702impl<T, S> FusedIterator for Difference<'_, T, S>
dfeec247
XL
1703where
1704 T: Eq + Hash,
1705 S: BuildHasher,
c30ab7b3
SL
1706{
1707}
9e0c209e 1708
8bb4bdeb 1709#[stable(feature = "std_debug", since = "1.16.0")]
9fa01778 1710impl<T, S> fmt::Debug for Difference<'_, T, S>
dfeec247
XL
1711where
1712 T: fmt::Debug + Eq + Hash,
1713 S: BuildHasher,
32a655c1 1714{
532ac7d7 1715 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
cc61c64b 1716 f.debug_list().entries(self.clone()).finish()
32a655c1
SL
1717 }
1718}
1719
92a42be0 1720#[stable(feature = "rust1", since = "1.0.0")]
9fa01778 1721impl<T, S> Clone for SymmetricDifference<'_, T, S> {
48663c56 1722 #[inline]
9fa01778 1723 fn clone(&self) -> Self {
c34b1796
AL
1724 SymmetricDifference { iter: self.iter.clone() }
1725 }
1726}
1727
85aaf69f
SL
1728#[stable(feature = "rust1", since = "1.0.0")]
1729impl<'a, T, S> Iterator for SymmetricDifference<'a, T, S>
dfeec247
XL
1730where
1731 T: Eq + Hash,
1732 S: BuildHasher,
1a4d82fc
JJ
1733{
1734 type Item = &'a T;
1735
48663c56 1736 #[inline]
c30ab7b3
SL
1737 fn next(&mut self) -> Option<&'a T> {
1738 self.iter.next()
1739 }
48663c56 1740 #[inline]
c30ab7b3
SL
1741 fn size_hint(&self) -> (usize, Option<usize>) {
1742 self.iter.size_hint()
1743 }
1a4d82fc
JJ
1744}
1745
0531ce1d 1746#[stable(feature = "fused", since = "1.26.0")]
9fa01778 1747impl<T, S> FusedIterator for SymmetricDifference<'_, T, S>
dfeec247
XL
1748where
1749 T: Eq + Hash,
1750 S: BuildHasher,
c30ab7b3
SL
1751{
1752}
9e0c209e 1753
8bb4bdeb 1754#[stable(feature = "std_debug", since = "1.16.0")]
9fa01778 1755impl<T, S> fmt::Debug for SymmetricDifference<'_, T, S>
dfeec247
XL
1756where
1757 T: fmt::Debug + Eq + Hash,
1758 S: BuildHasher,
32a655c1 1759{
532ac7d7 1760 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
cc61c64b 1761 f.debug_list().entries(self.clone()).finish()
32a655c1
SL
1762 }
1763}
1764
92a42be0 1765#[stable(feature = "rust1", since = "1.0.0")]
9fa01778 1766impl<T, S> Clone for Union<'_, T, S> {
48663c56 1767 #[inline]
9fa01778 1768 fn clone(&self) -> Self {
c30ab7b3
SL
1769 Union { iter: self.iter.clone() }
1770 }
c34b1796
AL
1771}
1772
0531ce1d 1773#[stable(feature = "fused", since = "1.26.0")]
9fa01778 1774impl<T, S> FusedIterator for Union<'_, T, S>
dfeec247
XL
1775where
1776 T: Eq + Hash,
1777 S: BuildHasher,
c30ab7b3
SL
1778{
1779}
9e0c209e 1780
8bb4bdeb 1781#[stable(feature = "std_debug", since = "1.16.0")]
9fa01778 1782impl<T, S> fmt::Debug for Union<'_, T, S>
dfeec247
XL
1783where
1784 T: fmt::Debug + Eq + Hash,
1785 S: BuildHasher,
32a655c1 1786{
532ac7d7 1787 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
cc61c64b 1788 f.debug_list().entries(self.clone()).finish()
32a655c1
SL
1789 }
1790}
1791
85aaf69f
SL
1792#[stable(feature = "rust1", since = "1.0.0")]
1793impl<'a, T, S> Iterator for Union<'a, T, S>
dfeec247
XL
1794where
1795 T: Eq + Hash,
1796 S: BuildHasher,
1a4d82fc
JJ
1797{
1798 type Item = &'a T;
1799
48663c56 1800 #[inline]
c30ab7b3
SL
1801 fn next(&mut self) -> Option<&'a T> {
1802 self.iter.next()
1803 }
48663c56 1804 #[inline]
c30ab7b3
SL
1805 fn size_hint(&self) -> (usize, Option<usize>) {
1806 self.iter.size_hint()
1807 }
1a4d82fc
JJ
1808}
1809
54a0048b
SL
1810#[allow(dead_code)]
1811fn assert_covariance() {
c30ab7b3
SL
1812 fn set<'new>(v: HashSet<&'static str>) -> HashSet<&'new str> {
1813 v
1814 }
1815 fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> {
1816 v
1817 }
1818 fn into_iter<'new>(v: IntoIter<&'static str>) -> IntoIter<&'new str> {
1819 v
1820 }
dfeec247
XL
1821 fn difference<'a, 'new>(
1822 v: Difference<'a, &'static str, RandomState>,
1823 ) -> Difference<'a, &'new str, RandomState> {
c30ab7b3
SL
1824 v
1825 }
dfeec247
XL
1826 fn symmetric_difference<'a, 'new>(
1827 v: SymmetricDifference<'a, &'static str, RandomState>,
1828 ) -> SymmetricDifference<'a, &'new str, RandomState> {
c30ab7b3
SL
1829 v
1830 }
dfeec247
XL
1831 fn intersection<'a, 'new>(
1832 v: Intersection<'a, &'static str, RandomState>,
1833 ) -> Intersection<'a, &'new str, RandomState> {
c30ab7b3
SL
1834 v
1835 }
dfeec247
XL
1836 fn union<'a, 'new>(
1837 v: Union<'a, &'static str, RandomState>,
1838 ) -> Union<'a, &'new str, RandomState> {
c30ab7b3
SL
1839 v
1840 }
1841 fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> {
1842 d
1843 }
54a0048b 1844}