]> git.proxmox.com Git - rustc.git/blame - src/libstd/collections/hash/set.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / libstd / collections / hash / set.rs
CommitLineData
1a4d82fc
JJ
1// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
1a4d82fc 10
85aaf69f 11use borrow::Borrow;
1a4d82fc 12use fmt;
9cc50fc6 13use hash::{Hash, BuildHasher};
54a0048b 14use iter::{Chain, FromIterator};
1a4d82fc 15use ops::{BitOr, BitAnd, BitXor, Sub};
1a4d82fc 16
e9174d1e 17use super::Recover;
62682a34 18use super::map::{self, HashMap, Keys, RandomState};
1a4d82fc 19
62682a34
SL
20const INITIAL_CAPACITY: usize = 32;
21
1a4d82fc
JJ
22// Future Optimization (FIXME!)
23// =============================
24//
25// Iteration over zero sized values is a noop. There is no need
26// for `bucket.val` in the case of HashSet. I suppose we would need HKT
27// to get rid of it properly.
28
29/// An implementation of a hash set using the underlying representation of a
d9579d0f
AL
30/// HashMap where the value is ().
31///
32/// As with the `HashMap` type, a `HashSet` requires that the elements
33/// implement the `Eq` and `Hash` traits. This can frequently be achieved by
34/// using `#[derive(PartialEq, Eq, Hash)]`. If you implement these yourself,
35/// it is important that the following property holds:
c34b1796
AL
36///
37/// ```text
38/// k1 == k2 -> hash(k1) == hash(k2)
39/// ```
40///
41/// In other words, if two keys are equal, their hashes must be equal.
1a4d82fc 42///
c34b1796
AL
43///
44/// It is a logic error for an item to be modified in such a way that the
45/// item's hash, as determined by the `Hash` trait, or its equality, as
46/// determined by the `Eq` trait, changes while it is in the set. This is
47/// normally only possible through `Cell`, `RefCell`, global state, I/O, or
48/// unsafe code.
49///
50/// # Examples
1a4d82fc
JJ
51///
52/// ```
53/// use std::collections::HashSet;
54/// // Type inference lets us omit an explicit type signature (which
55/// // would be `HashSet<&str>` in this example).
56/// let mut books = HashSet::new();
57///
58/// // Add some books.
59/// books.insert("A Dance With Dragons");
60/// books.insert("To Kill a Mockingbird");
61/// books.insert("The Odyssey");
62/// books.insert("The Great Gatsby");
63///
64/// // Check for a specific one.
d9579d0f 65/// if !books.contains("The Winds of Winter") {
1a4d82fc
JJ
66/// println!("We have {} books, but The Winds of Winter ain't one.",
67/// books.len());
68/// }
69///
70/// // Remove a book.
d9579d0f 71/// books.remove("The Odyssey");
1a4d82fc
JJ
72///
73/// // Iterate over everything.
d9579d0f
AL
74/// for book in &books {
75/// println!("{}", book);
1a4d82fc
JJ
76/// }
77/// ```
78///
79/// The easiest way to use `HashSet` with a custom type is to derive
80/// `Eq` and `Hash`. We must also derive `PartialEq`, this will in the
81/// future be implied by `Eq`.
82///
83/// ```
84/// use std::collections::HashSet;
85aaf69f 85/// #[derive(Hash, Eq, PartialEq, Debug)]
1a4d82fc
JJ
86/// struct Viking<'a> {
87/// name: &'a str,
85aaf69f 88/// power: usize,
1a4d82fc
JJ
89/// }
90///
91/// let mut vikings = HashSet::new();
92///
85aaf69f
SL
93/// vikings.insert(Viking { name: "Einar", power: 9 });
94/// vikings.insert(Viking { name: "Einar", power: 9 });
95/// vikings.insert(Viking { name: "Olaf", power: 4 });
96/// vikings.insert(Viking { name: "Harald", power: 8 });
1a4d82fc
JJ
97///
98/// // Use derived implementation to print the vikings.
d9579d0f 99/// for x in &vikings {
1a4d82fc
JJ
100/// println!("{:?}", x);
101/// }
102/// ```
103#[derive(Clone)]
85aaf69f 104#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
105pub struct HashSet<T, S = RandomState> {
106 map: HashMap<T, (), S>
107}
108
85aaf69f 109impl<T: Hash + Eq> HashSet<T, RandomState> {
9346a6ac 110 /// Creates an empty HashSet.
1a4d82fc 111 ///
c34b1796 112 /// # Examples
1a4d82fc
JJ
113 ///
114 /// ```
115 /// use std::collections::HashSet;
85aaf69f 116 /// let mut set: HashSet<i32> = HashSet::new();
1a4d82fc
JJ
117 /// ```
118 #[inline]
85aaf69f 119 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
120 pub fn new() -> HashSet<T, RandomState> {
121 HashSet::with_capacity(INITIAL_CAPACITY)
122 }
123
9346a6ac 124 /// Creates an empty HashSet with space for at least `n` elements in
1a4d82fc
JJ
125 /// the hash table.
126 ///
c34b1796 127 /// # Examples
1a4d82fc
JJ
128 ///
129 /// ```
130 /// use std::collections::HashSet;
85aaf69f 131 /// let mut set: HashSet<i32> = HashSet::with_capacity(10);
1a4d82fc
JJ
132 /// ```
133 #[inline]
85aaf69f
SL
134 #[stable(feature = "rust1", since = "1.0.0")]
135 pub fn with_capacity(capacity: usize) -> HashSet<T, RandomState> {
1a4d82fc
JJ
136 HashSet { map: HashMap::with_capacity(capacity) }
137 }
138}
139
85aaf69f 140impl<T, S> HashSet<T, S>
9cc50fc6 141 where T: Eq + Hash, S: BuildHasher
1a4d82fc
JJ
142{
143 /// Creates a new empty hash set which will use the given hasher to hash
144 /// keys.
145 ///
146 /// The hash set is also created with the default initial capacity.
147 ///
9cc50fc6
SL
148 /// Warning: `hasher` is normally randomly generated, and
149 /// is designed to allow `HashSet`s to be resistant to attacks that
150 /// cause many collisions and very poor performance. Setting it
151 /// manually using this function can expose a DoS attack vector.
152 ///
c34b1796 153 /// # Examples
1a4d82fc
JJ
154 ///
155 /// ```
156 /// use std::collections::HashSet;
157 /// use std::collections::hash_map::RandomState;
158 ///
159 /// let s = RandomState::new();
9cc50fc6 160 /// let mut set = HashSet::with_hasher(s);
85aaf69f 161 /// set.insert(2);
1a4d82fc
JJ
162 /// ```
163 #[inline]
9cc50fc6
SL
164 #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
165 pub fn with_hasher(hasher: S) -> HashSet<T, S> {
166 HashSet::with_capacity_and_hasher(INITIAL_CAPACITY, hasher)
1a4d82fc
JJ
167 }
168
9346a6ac 169 /// Creates an empty HashSet with space for at least `capacity`
1a4d82fc
JJ
170 /// elements in the hash table, using `hasher` to hash the keys.
171 ///
172 /// Warning: `hasher` is normally randomly generated, and
173 /// is designed to allow `HashSet`s to be resistant to attacks that
174 /// cause many collisions and very poor performance. Setting it
175 /// manually using this function can expose a DoS attack vector.
176 ///
c34b1796 177 /// # Examples
1a4d82fc
JJ
178 ///
179 /// ```
180 /// use std::collections::HashSet;
181 /// use std::collections::hash_map::RandomState;
182 ///
183 /// let s = RandomState::new();
9cc50fc6 184 /// let mut set = HashSet::with_capacity_and_hasher(10, s);
85aaf69f 185 /// set.insert(1);
1a4d82fc
JJ
186 /// ```
187 #[inline]
9cc50fc6
SL
188 #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
189 pub fn with_capacity_and_hasher(capacity: usize, hasher: S)
190 -> HashSet<T, S> {
191 HashSet {
192 map: HashMap::with_capacity_and_hasher(capacity, hasher),
193 }
194 }
195
7453a54e 196 /// Returns a reference to the set's hasher.
54a0048b 197 #[stable(feature = "hashmap_public_hasher", since = "1.9.0")]
7453a54e
SL
198 pub fn hasher(&self) -> &S {
199 self.map.hasher()
200 }
201
1a4d82fc
JJ
202 /// Returns the number of elements the set can hold without reallocating.
203 ///
c34b1796 204 /// # Examples
1a4d82fc
JJ
205 ///
206 /// ```
207 /// use std::collections::HashSet;
85aaf69f 208 /// let set: HashSet<i32> = HashSet::with_capacity(100);
1a4d82fc
JJ
209 /// assert!(set.capacity() >= 100);
210 /// ```
211 #[inline]
85aaf69f
SL
212 #[stable(feature = "rust1", since = "1.0.0")]
213 pub fn capacity(&self) -> usize {
1a4d82fc
JJ
214 self.map.capacity()
215 }
216
217 /// Reserves capacity for at least `additional` more elements to be inserted
218 /// in the `HashSet`. The collection may reserve more space to avoid
219 /// frequent reallocations.
220 ///
221 /// # Panics
222 ///
85aaf69f 223 /// Panics if the new allocation size overflows `usize`.
1a4d82fc 224 ///
c34b1796 225 /// # Examples
1a4d82fc
JJ
226 ///
227 /// ```
228 /// use std::collections::HashSet;
85aaf69f 229 /// let mut set: HashSet<i32> = HashSet::new();
1a4d82fc
JJ
230 /// set.reserve(10);
231 /// ```
85aaf69f
SL
232 #[stable(feature = "rust1", since = "1.0.0")]
233 pub fn reserve(&mut self, additional: usize) {
1a4d82fc
JJ
234 self.map.reserve(additional)
235 }
236
237 /// Shrinks the capacity of the set as much as possible. It will drop
238 /// down as much as possible while maintaining the internal rules
239 /// and possibly leaving some space in accordance with the resize policy.
240 ///
c34b1796 241 /// # Examples
1a4d82fc
JJ
242 ///
243 /// ```
244 /// use std::collections::HashSet;
245 ///
85aaf69f 246 /// let mut set = HashSet::with_capacity(100);
1a4d82fc
JJ
247 /// set.insert(1);
248 /// set.insert(2);
249 /// assert!(set.capacity() >= 100);
250 /// set.shrink_to_fit();
251 /// assert!(set.capacity() >= 2);
252 /// ```
85aaf69f 253 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
254 pub fn shrink_to_fit(&mut self) {
255 self.map.shrink_to_fit()
256 }
257
258 /// An iterator visiting all elements in arbitrary order.
259 /// Iterator element type is &'a T.
260 ///
c34b1796 261 /// # Examples
1a4d82fc
JJ
262 ///
263 /// ```
264 /// use std::collections::HashSet;
265 /// let mut set = HashSet::new();
266 /// set.insert("a");
267 /// set.insert("b");
268 ///
269 /// // Will print in an arbitrary order.
270 /// for x in set.iter() {
271 /// println!("{}", x);
272 /// }
273 /// ```
85aaf69f 274 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
275 pub fn iter(&self) -> Iter<T> {
276 Iter { iter: self.map.keys() }
277 }
278
1a4d82fc
JJ
279 /// Visit the values representing the difference.
280 ///
c34b1796 281 /// # Examples
1a4d82fc
JJ
282 ///
283 /// ```
284 /// use std::collections::HashSet;
85aaf69f
SL
285 /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect();
286 /// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
1a4d82fc
JJ
287 ///
288 /// // Can be seen as `a - b`.
289 /// for x in a.difference(&b) {
290 /// println!("{}", x); // Print 1
291 /// }
292 ///
85aaf69f
SL
293 /// let diff: HashSet<_> = a.difference(&b).cloned().collect();
294 /// assert_eq!(diff, [1].iter().cloned().collect());
1a4d82fc
JJ
295 ///
296 /// // Note that difference is not symmetric,
297 /// // and `b - a` means something else:
85aaf69f
SL
298 /// let diff: HashSet<_> = b.difference(&a).cloned().collect();
299 /// assert_eq!(diff, [4].iter().cloned().collect());
1a4d82fc 300 /// ```
85aaf69f 301 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
302 pub fn difference<'a>(&'a self, other: &'a HashSet<T, S>) -> Difference<'a, T, S> {
303 Difference {
304 iter: self.iter(),
305 other: other,
306 }
307 }
308
309 /// Visit the values representing the symmetric difference.
310 ///
c34b1796 311 /// # Examples
1a4d82fc
JJ
312 ///
313 /// ```
314 /// use std::collections::HashSet;
85aaf69f
SL
315 /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect();
316 /// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
1a4d82fc
JJ
317 ///
318 /// // Print 1, 4 in arbitrary order.
319 /// for x in a.symmetric_difference(&b) {
320 /// println!("{}", x);
321 /// }
322 ///
85aaf69f
SL
323 /// let diff1: HashSet<_> = a.symmetric_difference(&b).cloned().collect();
324 /// let diff2: HashSet<_> = b.symmetric_difference(&a).cloned().collect();
1a4d82fc
JJ
325 ///
326 /// assert_eq!(diff1, diff2);
85aaf69f 327 /// assert_eq!(diff1, [1, 4].iter().cloned().collect());
1a4d82fc 328 /// ```
85aaf69f 329 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
330 pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet<T, S>)
331 -> SymmetricDifference<'a, T, S> {
332 SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) }
333 }
334
335 /// Visit the values representing the intersection.
336 ///
c34b1796 337 /// # Examples
1a4d82fc
JJ
338 ///
339 /// ```
340 /// use std::collections::HashSet;
85aaf69f
SL
341 /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect();
342 /// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
1a4d82fc
JJ
343 ///
344 /// // Print 2, 3 in arbitrary order.
345 /// for x in a.intersection(&b) {
346 /// println!("{}", x);
347 /// }
348 ///
92a42be0
SL
349 /// let intersection: HashSet<_> = a.intersection(&b).cloned().collect();
350 /// assert_eq!(intersection, [2, 3].iter().cloned().collect());
1a4d82fc 351 /// ```
85aaf69f 352 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
353 pub fn intersection<'a>(&'a self, other: &'a HashSet<T, S>) -> Intersection<'a, T, S> {
354 Intersection {
355 iter: self.iter(),
356 other: other,
357 }
358 }
359
360 /// Visit the values representing the union.
361 ///
c34b1796 362 /// # Examples
1a4d82fc
JJ
363 ///
364 /// ```
365 /// use std::collections::HashSet;
85aaf69f
SL
366 /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect();
367 /// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
1a4d82fc
JJ
368 ///
369 /// // Print 1, 2, 3, 4 in arbitrary order.
370 /// for x in a.union(&b) {
371 /// println!("{}", x);
372 /// }
373 ///
92a42be0
SL
374 /// let union: HashSet<_> = a.union(&b).cloned().collect();
375 /// assert_eq!(union, [1, 2, 3, 4].iter().cloned().collect());
1a4d82fc 376 /// ```
85aaf69f 377 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
378 pub fn union<'a>(&'a self, other: &'a HashSet<T, S>) -> Union<'a, T, S> {
379 Union { iter: self.iter().chain(other.difference(self)) }
380 }
381
9346a6ac 382 /// Returns the number of elements in the set.
1a4d82fc 383 ///
c34b1796 384 /// # Examples
1a4d82fc
JJ
385 ///
386 /// ```
387 /// use std::collections::HashSet;
388 ///
389 /// let mut v = HashSet::new();
390 /// assert_eq!(v.len(), 0);
85aaf69f 391 /// v.insert(1);
1a4d82fc
JJ
392 /// assert_eq!(v.len(), 1);
393 /// ```
85aaf69f
SL
394 #[stable(feature = "rust1", since = "1.0.0")]
395 pub fn len(&self) -> usize { self.map.len() }
1a4d82fc 396
9346a6ac 397 /// Returns true if the set contains no elements.
1a4d82fc 398 ///
c34b1796 399 /// # Examples
1a4d82fc
JJ
400 ///
401 /// ```
402 /// use std::collections::HashSet;
403 ///
404 /// let mut v = HashSet::new();
405 /// assert!(v.is_empty());
85aaf69f 406 /// v.insert(1);
1a4d82fc
JJ
407 /// assert!(!v.is_empty());
408 /// ```
85aaf69f 409 #[stable(feature = "rust1", since = "1.0.0")]
9346a6ac 410 pub fn is_empty(&self) -> bool { self.map.is_empty() }
1a4d82fc
JJ
411
412 /// Clears the set, returning all elements in an iterator.
413 #[inline]
92a42be0 414 #[stable(feature = "drain", since = "1.6.0")]
1a4d82fc 415 pub fn drain(&mut self) -> Drain<T> {
54a0048b 416 Drain { iter: self.map.drain() }
1a4d82fc
JJ
417 }
418
419 /// Clears the set, removing all values.
420 ///
c34b1796 421 /// # Examples
1a4d82fc
JJ
422 ///
423 /// ```
424 /// use std::collections::HashSet;
425 ///
426 /// let mut v = HashSet::new();
85aaf69f 427 /// v.insert(1);
1a4d82fc
JJ
428 /// v.clear();
429 /// assert!(v.is_empty());
430 /// ```
85aaf69f 431 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
432 pub fn clear(&mut self) { self.map.clear() }
433
434 /// Returns `true` if the set contains a value.
435 ///
436 /// The value may be any borrowed form of the set's value type, but
437 /// `Hash` and `Eq` on the borrowed form *must* match those for
438 /// the value type.
439 ///
c34b1796 440 /// # Examples
1a4d82fc
JJ
441 ///
442 /// ```
443 /// use std::collections::HashSet;
444 ///
85aaf69f 445 /// let set: HashSet<_> = [1, 2, 3].iter().cloned().collect();
1a4d82fc
JJ
446 /// assert_eq!(set.contains(&1), true);
447 /// assert_eq!(set.contains(&4), false);
448 /// ```
85aaf69f 449 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 450 pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
85aaf69f 451 where T: Borrow<Q>, Q: Hash + Eq
1a4d82fc
JJ
452 {
453 self.map.contains_key(value)
454 }
455
e9174d1e
SL
456 /// Returns a reference to the value in the set, if any, that is equal to the given value.
457 ///
458 /// The value may be any borrowed form of the set's value type, but
459 /// `Hash` and `Eq` on the borrowed form *must* match those for
460 /// the value type.
54a0048b 461 #[stable(feature = "set_recovery", since = "1.9.0")]
e9174d1e
SL
462 pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T>
463 where T: Borrow<Q>, Q: Hash + Eq
464 {
465 Recover::get(&self.map, value)
466 }
467
1a4d82fc
JJ
468 /// Returns `true` if the set has no elements in common with `other`.
469 /// This is equivalent to checking for an empty intersection.
470 ///
c34b1796 471 /// # Examples
1a4d82fc
JJ
472 ///
473 /// ```
474 /// use std::collections::HashSet;
475 ///
85aaf69f
SL
476 /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect();
477 /// let mut b = HashSet::new();
1a4d82fc
JJ
478 ///
479 /// assert_eq!(a.is_disjoint(&b), true);
480 /// b.insert(4);
481 /// assert_eq!(a.is_disjoint(&b), true);
482 /// b.insert(1);
483 /// assert_eq!(a.is_disjoint(&b), false);
484 /// ```
85aaf69f 485 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
486 pub fn is_disjoint(&self, other: &HashSet<T, S>) -> bool {
487 self.iter().all(|v| !other.contains(v))
488 }
489
490 /// Returns `true` if the set is a subset of another.
491 ///
c34b1796 492 /// # Examples
1a4d82fc
JJ
493 ///
494 /// ```
495 /// use std::collections::HashSet;
496 ///
85aaf69f
SL
497 /// let sup: HashSet<_> = [1, 2, 3].iter().cloned().collect();
498 /// let mut set = HashSet::new();
1a4d82fc
JJ
499 ///
500 /// assert_eq!(set.is_subset(&sup), true);
501 /// set.insert(2);
502 /// assert_eq!(set.is_subset(&sup), true);
503 /// set.insert(4);
504 /// assert_eq!(set.is_subset(&sup), false);
505 /// ```
85aaf69f 506 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
507 pub fn is_subset(&self, other: &HashSet<T, S>) -> bool {
508 self.iter().all(|v| other.contains(v))
509 }
510
511 /// Returns `true` if the set is a superset of another.
512 ///
c34b1796 513 /// # Examples
1a4d82fc
JJ
514 ///
515 /// ```
516 /// use std::collections::HashSet;
517 ///
85aaf69f
SL
518 /// let sub: HashSet<_> = [1, 2].iter().cloned().collect();
519 /// let mut set = HashSet::new();
1a4d82fc
JJ
520 ///
521 /// assert_eq!(set.is_superset(&sub), false);
522 ///
523 /// set.insert(0);
524 /// set.insert(1);
525 /// assert_eq!(set.is_superset(&sub), false);
526 ///
527 /// set.insert(2);
528 /// assert_eq!(set.is_superset(&sub), true);
529 /// ```
530 #[inline]
85aaf69f 531 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
532 pub fn is_superset(&self, other: &HashSet<T, S>) -> bool {
533 other.is_subset(self)
534 }
535
b039eaaf
SL
536 /// Adds a value to the set.
537 ///
538 /// If the set did not have a value present, `true` is returned.
539 ///
92a42be0 540 /// If the set did have this key present, `false` is returned.
1a4d82fc 541 ///
c34b1796 542 /// # Examples
1a4d82fc
JJ
543 ///
544 /// ```
545 /// use std::collections::HashSet;
546 ///
547 /// let mut set = HashSet::new();
548 ///
85aaf69f 549 /// assert_eq!(set.insert(2), true);
1a4d82fc
JJ
550 /// assert_eq!(set.insert(2), false);
551 /// assert_eq!(set.len(), 1);
552 /// ```
85aaf69f 553 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
554 pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()).is_none() }
555
e9174d1e
SL
556 /// Adds a value to the set, replacing the existing value, if any, that is equal to the given
557 /// one. Returns the replaced value.
54a0048b 558 #[stable(feature = "set_recovery", since = "1.9.0")]
e9174d1e
SL
559 pub fn replace(&mut self, value: T) -> Option<T> {
560 Recover::replace(&mut self.map, value)
561 }
562
1a4d82fc
JJ
563 /// Removes a value from the set. Returns `true` if the value was
564 /// present in the set.
565 ///
566 /// The value may be any borrowed form of the set's value type, but
567 /// `Hash` and `Eq` on the borrowed form *must* match those for
568 /// the value type.
569 ///
c34b1796 570 /// # Examples
1a4d82fc
JJ
571 ///
572 /// ```
573 /// use std::collections::HashSet;
574 ///
575 /// let mut set = HashSet::new();
576 ///
85aaf69f 577 /// set.insert(2);
1a4d82fc
JJ
578 /// assert_eq!(set.remove(&2), true);
579 /// assert_eq!(set.remove(&2), false);
580 /// ```
85aaf69f 581 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 582 pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
85aaf69f 583 where T: Borrow<Q>, Q: Hash + Eq
1a4d82fc
JJ
584 {
585 self.map.remove(value).is_some()
586 }
e9174d1e
SL
587
588 /// Removes and returns the value in the set, if any, that is equal to the given one.
589 ///
590 /// The value may be any borrowed form of the set's value type, but
591 /// `Hash` and `Eq` on the borrowed form *must* match those for
592 /// the value type.
54a0048b 593 #[stable(feature = "set_recovery", since = "1.9.0")]
e9174d1e
SL
594 pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T>
595 where T: Borrow<Q>, Q: Hash + Eq
596 {
597 Recover::take(&mut self.map, value)
598 }
1a4d82fc
JJ
599}
600
85aaf69f
SL
601#[stable(feature = "rust1", since = "1.0.0")]
602impl<T, S> PartialEq for HashSet<T, S>
9cc50fc6 603 where T: Eq + Hash, S: BuildHasher
1a4d82fc
JJ
604{
605 fn eq(&self, other: &HashSet<T, S>) -> bool {
606 if self.len() != other.len() { return false; }
607
608 self.iter().all(|key| other.contains(key))
609 }
610}
611
85aaf69f
SL
612#[stable(feature = "rust1", since = "1.0.0")]
613impl<T, S> Eq for HashSet<T, S>
9cc50fc6 614 where T: Eq + Hash, S: BuildHasher
1a4d82fc
JJ
615{}
616
85aaf69f
SL
617#[stable(feature = "rust1", since = "1.0.0")]
618impl<T, S> fmt::Debug for HashSet<T, S>
619 where T: Eq + Hash + fmt::Debug,
9cc50fc6 620 S: BuildHasher
1a4d82fc
JJ
621{
622 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
62682a34 623 f.debug_set().entries(self.iter()).finish()
1a4d82fc
JJ
624 }
625}
626
85aaf69f
SL
627#[stable(feature = "rust1", since = "1.0.0")]
628impl<T, S> FromIterator<T> for HashSet<T, S>
629 where T: Eq + Hash,
9cc50fc6 630 S: BuildHasher + Default,
1a4d82fc 631{
54a0048b
SL
632 fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> HashSet<T, S> {
633 let iterator = iter.into_iter();
634 let lower = iterator.size_hint().0;
9cc50fc6 635 let mut set = HashSet::with_capacity_and_hasher(lower, Default::default());
54a0048b 636 set.extend(iterator);
1a4d82fc
JJ
637 set
638 }
639}
640
85aaf69f
SL
641#[stable(feature = "rust1", since = "1.0.0")]
642impl<T, S> Extend<T> for HashSet<T, S>
643 where T: Eq + Hash,
9cc50fc6 644 S: BuildHasher,
1a4d82fc 645{
85aaf69f 646 fn extend<I: IntoIterator<Item=T>>(&mut self, iter: I) {
1a4d82fc
JJ
647 for k in iter {
648 self.insert(k);
649 }
650 }
651}
652
e9174d1e
SL
653#[stable(feature = "hash_extend_copy", since = "1.4.0")]
654impl<'a, T, S> Extend<&'a T> for HashSet<T, S>
655 where T: 'a + Eq + Hash + Copy,
9cc50fc6 656 S: BuildHasher,
e9174d1e
SL
657{
658 fn extend<I: IntoIterator<Item=&'a T>>(&mut self, iter: I) {
659 self.extend(iter.into_iter().cloned());
660 }
661}
662
85aaf69f
SL
663#[stable(feature = "rust1", since = "1.0.0")]
664impl<T, S> Default for HashSet<T, S>
665 where T: Eq + Hash,
9cc50fc6 666 S: BuildHasher + Default,
1a4d82fc 667{
1a4d82fc 668 fn default() -> HashSet<T, S> {
9cc50fc6 669 HashSet::with_hasher(Default::default())
1a4d82fc
JJ
670 }
671}
672
85aaf69f
SL
673#[stable(feature = "rust1", since = "1.0.0")]
674impl<'a, 'b, T, S> BitOr<&'b HashSet<T, S>> for &'a HashSet<T, S>
675 where T: Eq + Hash + Clone,
9cc50fc6 676 S: BuildHasher + Default,
1a4d82fc
JJ
677{
678 type Output = HashSet<T, S>;
679
680 /// Returns the union of `self` and `rhs` as a new `HashSet<T, S>`.
681 ///
682 /// # Examples
683 ///
684 /// ```
685 /// use std::collections::HashSet;
686 ///
85aaf69f
SL
687 /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
688 /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
1a4d82fc 689 ///
85aaf69f 690 /// let set = &a | &b;
1a4d82fc
JJ
691 ///
692 /// let mut i = 0;
693 /// let expected = [1, 2, 3, 4, 5];
62682a34 694 /// for x in &set {
1a4d82fc
JJ
695 /// assert!(expected.contains(x));
696 /// i += 1;
697 /// }
698 /// assert_eq!(i, expected.len());
699 /// ```
700 fn bitor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
701 self.union(rhs).cloned().collect()
702 }
703}
704
85aaf69f
SL
705#[stable(feature = "rust1", since = "1.0.0")]
706impl<'a, 'b, T, S> BitAnd<&'b HashSet<T, S>> for &'a HashSet<T, S>
707 where T: Eq + Hash + Clone,
9cc50fc6 708 S: BuildHasher + Default,
1a4d82fc
JJ
709{
710 type Output = HashSet<T, S>;
711
712 /// Returns the intersection of `self` and `rhs` as a new `HashSet<T, S>`.
713 ///
714 /// # Examples
715 ///
716 /// ```
717 /// use std::collections::HashSet;
718 ///
85aaf69f
SL
719 /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
720 /// let b: HashSet<_> = vec![2, 3, 4].into_iter().collect();
1a4d82fc 721 ///
85aaf69f 722 /// let set = &a & &b;
1a4d82fc
JJ
723 ///
724 /// let mut i = 0;
725 /// let expected = [2, 3];
62682a34 726 /// for x in &set {
1a4d82fc
JJ
727 /// assert!(expected.contains(x));
728 /// i += 1;
729 /// }
730 /// assert_eq!(i, expected.len());
731 /// ```
732 fn bitand(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
733 self.intersection(rhs).cloned().collect()
734 }
735}
736
85aaf69f
SL
737#[stable(feature = "rust1", since = "1.0.0")]
738impl<'a, 'b, T, S> BitXor<&'b HashSet<T, S>> for &'a HashSet<T, S>
739 where T: Eq + Hash + Clone,
9cc50fc6 740 S: BuildHasher + Default,
1a4d82fc
JJ
741{
742 type Output = HashSet<T, S>;
743
744 /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet<T, S>`.
745 ///
746 /// # Examples
747 ///
748 /// ```
749 /// use std::collections::HashSet;
750 ///
85aaf69f
SL
751 /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
752 /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
1a4d82fc 753 ///
85aaf69f 754 /// let set = &a ^ &b;
1a4d82fc
JJ
755 ///
756 /// let mut i = 0;
757 /// let expected = [1, 2, 4, 5];
62682a34 758 /// for x in &set {
1a4d82fc
JJ
759 /// assert!(expected.contains(x));
760 /// i += 1;
761 /// }
762 /// assert_eq!(i, expected.len());
763 /// ```
764 fn bitxor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
765 self.symmetric_difference(rhs).cloned().collect()
766 }
767}
768
85aaf69f
SL
769#[stable(feature = "rust1", since = "1.0.0")]
770impl<'a, 'b, T, S> Sub<&'b HashSet<T, S>> for &'a HashSet<T, S>
771 where T: Eq + Hash + Clone,
9cc50fc6 772 S: BuildHasher + Default,
1a4d82fc
JJ
773{
774 type Output = HashSet<T, S>;
775
776 /// Returns the difference of `self` and `rhs` as a new `HashSet<T, S>`.
777 ///
778 /// # Examples
779 ///
780 /// ```
781 /// use std::collections::HashSet;
782 ///
85aaf69f
SL
783 /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
784 /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
1a4d82fc 785 ///
85aaf69f 786 /// let set = &a - &b;
1a4d82fc
JJ
787 ///
788 /// let mut i = 0;
789 /// let expected = [1, 2];
62682a34 790 /// for x in &set {
1a4d82fc
JJ
791 /// assert!(expected.contains(x));
792 /// i += 1;
793 /// }
794 /// assert_eq!(i, expected.len());
795 /// ```
796 fn sub(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
797 self.difference(rhs).cloned().collect()
798 }
799}
800
801/// HashSet iterator
85aaf69f 802#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
803pub struct Iter<'a, K: 'a> {
804 iter: Keys<'a, K, ()>
805}
806
807/// HashSet move iterator
85aaf69f 808#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 809pub struct IntoIter<K> {
54a0048b 810 iter: map::IntoIter<K, ()>
1a4d82fc
JJ
811}
812
813/// HashSet drain iterator
85aaf69f 814#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 815pub struct Drain<'a, K: 'a> {
54a0048b 816 iter: map::Drain<'a, K, ()>,
1a4d82fc
JJ
817}
818
819/// Intersection iterator
85aaf69f 820#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
821pub struct Intersection<'a, T: 'a, S: 'a> {
822 // iterator of the first set
823 iter: Iter<'a, T>,
824 // the second set
825 other: &'a HashSet<T, S>,
826}
827
828/// Difference iterator
85aaf69f 829#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
830pub struct Difference<'a, T: 'a, S: 'a> {
831 // iterator of the first set
832 iter: Iter<'a, T>,
833 // the second set
834 other: &'a HashSet<T, S>,
835}
836
837/// Symmetric difference iterator.
85aaf69f 838#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
839pub struct SymmetricDifference<'a, T: 'a, S: 'a> {
840 iter: Chain<Difference<'a, T, S>, Difference<'a, T, S>>
841}
842
843/// Set union iterator.
85aaf69f 844#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
845pub struct Union<'a, T: 'a, S: 'a> {
846 iter: Chain<Iter<'a, T>, Difference<'a, T, S>>
847}
848
85aaf69f
SL
849#[stable(feature = "rust1", since = "1.0.0")]
850impl<'a, T, S> IntoIterator for &'a HashSet<T, S>
9cc50fc6 851 where T: Eq + Hash, S: BuildHasher
85aaf69f
SL
852{
853 type Item = &'a T;
854 type IntoIter = Iter<'a, T>;
855
856 fn into_iter(self) -> Iter<'a, T> {
857 self.iter()
858 }
859}
860
861#[stable(feature = "rust1", since = "1.0.0")]
862impl<T, S> IntoIterator for HashSet<T, S>
863 where T: Eq + Hash,
9cc50fc6 864 S: BuildHasher
85aaf69f
SL
865{
866 type Item = T;
867 type IntoIter = IntoIter<T>;
868
9346a6ac
AL
869 /// Creates a consuming iterator, that is, one that moves each value out
870 /// of the set in arbitrary order. The set cannot be used after calling
871 /// this.
872 ///
873 /// # Examples
874 ///
875 /// ```
876 /// use std::collections::HashSet;
877 /// let mut set = HashSet::new();
878 /// set.insert("a".to_string());
879 /// set.insert("b".to_string());
880 ///
881 /// // Not possible to collect to a Vec<String> with a regular `.iter()`.
882 /// let v: Vec<String> = set.into_iter().collect();
883 ///
884 /// // Will print in an arbitrary order.
62682a34 885 /// for x in &v {
9346a6ac
AL
886 /// println!("{}", x);
887 /// }
888 /// ```
85aaf69f 889 fn into_iter(self) -> IntoIter<T> {
54a0048b 890 IntoIter { iter: self.map.into_iter() }
85aaf69f
SL
891 }
892}
893
92a42be0 894#[stable(feature = "rust1", since = "1.0.0")]
c34b1796
AL
895impl<'a, K> Clone for Iter<'a, K> {
896 fn clone(&self) -> Iter<'a, K> { Iter { iter: self.iter.clone() } }
897}
85aaf69f 898#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
899impl<'a, K> Iterator for Iter<'a, K> {
900 type Item = &'a K;
901
902 fn next(&mut self) -> Option<&'a K> { self.iter.next() }
85aaf69f
SL
903 fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
904}
905#[stable(feature = "rust1", since = "1.0.0")]
906impl<'a, K> ExactSizeIterator for Iter<'a, K> {
907 fn len(&self) -> usize { self.iter.len() }
1a4d82fc
JJ
908}
909
85aaf69f 910#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
911impl<K> Iterator for IntoIter<K> {
912 type Item = K;
913
54a0048b 914 fn next(&mut self) -> Option<K> { self.iter.next().map(|(k, _)| k) }
85aaf69f
SL
915 fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
916}
917#[stable(feature = "rust1", since = "1.0.0")]
918impl<K> ExactSizeIterator for IntoIter<K> {
919 fn len(&self) -> usize { self.iter.len() }
1a4d82fc
JJ
920}
921
85aaf69f
SL
922#[stable(feature = "rust1", since = "1.0.0")]
923impl<'a, K> Iterator for Drain<'a, K> {
1a4d82fc
JJ
924 type Item = K;
925
54a0048b 926 fn next(&mut self) -> Option<K> { self.iter.next().map(|(k, _)| k) }
85aaf69f
SL
927 fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
928}
929#[stable(feature = "rust1", since = "1.0.0")]
930impl<'a, K> ExactSizeIterator for Drain<'a, K> {
931 fn len(&self) -> usize { self.iter.len() }
1a4d82fc
JJ
932}
933
92a42be0 934#[stable(feature = "rust1", since = "1.0.0")]
c34b1796
AL
935impl<'a, T, S> Clone for Intersection<'a, T, S> {
936 fn clone(&self) -> Intersection<'a, T, S> {
937 Intersection { iter: self.iter.clone(), ..*self }
938 }
939}
940
85aaf69f
SL
941#[stable(feature = "rust1", since = "1.0.0")]
942impl<'a, T, S> Iterator for Intersection<'a, T, S>
9cc50fc6 943 where T: Eq + Hash, S: BuildHasher
1a4d82fc
JJ
944{
945 type Item = &'a T;
946
947 fn next(&mut self) -> Option<&'a T> {
948 loop {
949 match self.iter.next() {
950 None => return None,
951 Some(elt) => if self.other.contains(elt) {
952 return Some(elt)
953 },
954 }
955 }
956 }
957
85aaf69f 958 fn size_hint(&self) -> (usize, Option<usize>) {
1a4d82fc
JJ
959 let (_, upper) = self.iter.size_hint();
960 (0, upper)
961 }
962}
963
92a42be0 964#[stable(feature = "rust1", since = "1.0.0")]
c34b1796
AL
965impl<'a, T, S> Clone for Difference<'a, T, S> {
966 fn clone(&self) -> Difference<'a, T, S> {
967 Difference { iter: self.iter.clone(), ..*self }
968 }
969}
970
85aaf69f
SL
971#[stable(feature = "rust1", since = "1.0.0")]
972impl<'a, T, S> Iterator for Difference<'a, T, S>
9cc50fc6 973 where T: Eq + Hash, S: BuildHasher
1a4d82fc
JJ
974{
975 type Item = &'a T;
976
977 fn next(&mut self) -> Option<&'a T> {
978 loop {
979 match self.iter.next() {
980 None => return None,
981 Some(elt) => if !self.other.contains(elt) {
982 return Some(elt)
983 },
984 }
985 }
986 }
987
85aaf69f 988 fn size_hint(&self) -> (usize, Option<usize>) {
1a4d82fc
JJ
989 let (_, upper) = self.iter.size_hint();
990 (0, upper)
991 }
992}
993
92a42be0 994#[stable(feature = "rust1", since = "1.0.0")]
c34b1796
AL
995impl<'a, T, S> Clone for SymmetricDifference<'a, T, S> {
996 fn clone(&self) -> SymmetricDifference<'a, T, S> {
997 SymmetricDifference { iter: self.iter.clone() }
998 }
999}
1000
85aaf69f
SL
1001#[stable(feature = "rust1", since = "1.0.0")]
1002impl<'a, T, S> Iterator for SymmetricDifference<'a, T, S>
9cc50fc6 1003 where T: Eq + Hash, S: BuildHasher
1a4d82fc
JJ
1004{
1005 type Item = &'a T;
1006
1007 fn next(&mut self) -> Option<&'a T> { self.iter.next() }
85aaf69f 1008 fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
1a4d82fc
JJ
1009}
1010
92a42be0 1011#[stable(feature = "rust1", since = "1.0.0")]
c34b1796
AL
1012impl<'a, T, S> Clone for Union<'a, T, S> {
1013 fn clone(&self) -> Union<'a, T, S> { Union { iter: self.iter.clone() } }
1014}
1015
85aaf69f
SL
1016#[stable(feature = "rust1", since = "1.0.0")]
1017impl<'a, T, S> Iterator for Union<'a, T, S>
9cc50fc6 1018 where T: Eq + Hash, S: BuildHasher
1a4d82fc
JJ
1019{
1020 type Item = &'a T;
1021
1022 fn next(&mut self) -> Option<&'a T> { self.iter.next() }
85aaf69f 1023 fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
1a4d82fc
JJ
1024}
1025
54a0048b
SL
1026#[allow(dead_code)]
1027fn assert_covariance() {
1028 fn set<'new>(v: HashSet<&'static str>) -> HashSet<&'new str> { v }
1029 fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> { v }
1030 fn into_iter<'new>(v: IntoIter<&'static str>) -> IntoIter<&'new str> { v }
1031 fn difference<'a, 'new>(v: Difference<'a, &'static str, RandomState>)
1032 -> Difference<'a, &'new str, RandomState> { v }
1033 fn symmetric_difference<'a, 'new>(v: SymmetricDifference<'a, &'static str, RandomState>)
1034 -> SymmetricDifference<'a, &'new str, RandomState> { v }
1035 fn intersection<'a, 'new>(v: Intersection<'a, &'static str, RandomState>)
1036 -> Intersection<'a, &'new str, RandomState> { v }
1037 fn union<'a, 'new>(v: Union<'a, &'static str, RandomState>)
1038 -> Union<'a, &'new str, RandomState> { v }
1039}
1040
1a4d82fc
JJ
1041#[cfg(test)]
1042mod test_set {
1043 use prelude::v1::*;
1044
1045 use super::HashSet;
1046
1047 #[test]
1048 fn test_disjoint() {
1049 let mut xs = HashSet::new();
1050 let mut ys = HashSet::new();
1051 assert!(xs.is_disjoint(&ys));
1052 assert!(ys.is_disjoint(&xs));
85aaf69f
SL
1053 assert!(xs.insert(5));
1054 assert!(ys.insert(11));
1a4d82fc
JJ
1055 assert!(xs.is_disjoint(&ys));
1056 assert!(ys.is_disjoint(&xs));
1057 assert!(xs.insert(7));
1058 assert!(xs.insert(19));
1059 assert!(xs.insert(4));
1060 assert!(ys.insert(2));
1061 assert!(ys.insert(-11));
1062 assert!(xs.is_disjoint(&ys));
1063 assert!(ys.is_disjoint(&xs));
1064 assert!(ys.insert(7));
1065 assert!(!xs.is_disjoint(&ys));
1066 assert!(!ys.is_disjoint(&xs));
1067 }
1068
1069 #[test]
1070 fn test_subset_and_superset() {
1071 let mut a = HashSet::new();
85aaf69f 1072 assert!(a.insert(0));
1a4d82fc
JJ
1073 assert!(a.insert(5));
1074 assert!(a.insert(11));
1075 assert!(a.insert(7));
1076
1077 let mut b = HashSet::new();
85aaf69f 1078 assert!(b.insert(0));
1a4d82fc
JJ
1079 assert!(b.insert(7));
1080 assert!(b.insert(19));
1081 assert!(b.insert(250));
1082 assert!(b.insert(11));
1083 assert!(b.insert(200));
1084
1085 assert!(!a.is_subset(&b));
1086 assert!(!a.is_superset(&b));
1087 assert!(!b.is_subset(&a));
1088 assert!(!b.is_superset(&a));
1089
1090 assert!(b.insert(5));
1091
1092 assert!(a.is_subset(&b));
1093 assert!(!a.is_superset(&b));
1094 assert!(!b.is_subset(&a));
1095 assert!(b.is_superset(&a));
1096 }
1097
1098 #[test]
1099 fn test_iterate() {
1100 let mut a = HashSet::new();
85aaf69f 1101 for i in 0..32 {
1a4d82fc
JJ
1102 assert!(a.insert(i));
1103 }
1104 let mut observed: u32 = 0;
85aaf69f 1105 for k in &a {
1a4d82fc
JJ
1106 observed |= 1 << *k;
1107 }
1108 assert_eq!(observed, 0xFFFF_FFFF);
1109 }
1110
1111 #[test]
1112 fn test_intersection() {
1113 let mut a = HashSet::new();
1114 let mut b = HashSet::new();
1115
85aaf69f 1116 assert!(a.insert(11));
1a4d82fc
JJ
1117 assert!(a.insert(1));
1118 assert!(a.insert(3));
1119 assert!(a.insert(77));
1120 assert!(a.insert(103));
1121 assert!(a.insert(5));
1122 assert!(a.insert(-5));
1123
85aaf69f 1124 assert!(b.insert(2));
1a4d82fc
JJ
1125 assert!(b.insert(11));
1126 assert!(b.insert(77));
1127 assert!(b.insert(-9));
1128 assert!(b.insert(-42));
1129 assert!(b.insert(5));
1130 assert!(b.insert(3));
1131
1132 let mut i = 0;
1133 let expected = [3, 5, 11, 77];
1134 for x in a.intersection(&b) {
1135 assert!(expected.contains(x));
1136 i += 1
1137 }
1138 assert_eq!(i, expected.len());
1139 }
1140
1141 #[test]
1142 fn test_difference() {
1143 let mut a = HashSet::new();
1144 let mut b = HashSet::new();
1145
85aaf69f 1146 assert!(a.insert(1));
1a4d82fc
JJ
1147 assert!(a.insert(3));
1148 assert!(a.insert(5));
1149 assert!(a.insert(9));
1150 assert!(a.insert(11));
1151
85aaf69f 1152 assert!(b.insert(3));
1a4d82fc
JJ
1153 assert!(b.insert(9));
1154
1155 let mut i = 0;
1156 let expected = [1, 5, 11];
1157 for x in a.difference(&b) {
1158 assert!(expected.contains(x));
1159 i += 1
1160 }
1161 assert_eq!(i, expected.len());
1162 }
1163
1164 #[test]
1165 fn test_symmetric_difference() {
1166 let mut a = HashSet::new();
1167 let mut b = HashSet::new();
1168
85aaf69f 1169 assert!(a.insert(1));
1a4d82fc
JJ
1170 assert!(a.insert(3));
1171 assert!(a.insert(5));
1172 assert!(a.insert(9));
1173 assert!(a.insert(11));
1174
85aaf69f 1175 assert!(b.insert(-2));
1a4d82fc
JJ
1176 assert!(b.insert(3));
1177 assert!(b.insert(9));
1178 assert!(b.insert(14));
1179 assert!(b.insert(22));
1180
1181 let mut i = 0;
1182 let expected = [-2, 1, 5, 11, 14, 22];
1183 for x in a.symmetric_difference(&b) {
1184 assert!(expected.contains(x));
1185 i += 1
1186 }
1187 assert_eq!(i, expected.len());
1188 }
1189
1190 #[test]
1191 fn test_union() {
1192 let mut a = HashSet::new();
1193 let mut b = HashSet::new();
1194
85aaf69f 1195 assert!(a.insert(1));
1a4d82fc
JJ
1196 assert!(a.insert(3));
1197 assert!(a.insert(5));
1198 assert!(a.insert(9));
1199 assert!(a.insert(11));
1200 assert!(a.insert(16));
1201 assert!(a.insert(19));
1202 assert!(a.insert(24));
1203
85aaf69f 1204 assert!(b.insert(-2));
1a4d82fc
JJ
1205 assert!(b.insert(1));
1206 assert!(b.insert(5));
1207 assert!(b.insert(9));
1208 assert!(b.insert(13));
1209 assert!(b.insert(19));
1210
1211 let mut i = 0;
1212 let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24];
1213 for x in a.union(&b) {
1214 assert!(expected.contains(x));
1215 i += 1
1216 }
1217 assert_eq!(i, expected.len());
1218 }
1219
1220 #[test]
1221 fn test_from_iter() {
85aaf69f 1222 let xs = [1, 2, 3, 4, 5, 6, 7, 8, 9];
1a4d82fc 1223
85aaf69f 1224 let set: HashSet<_> = xs.iter().cloned().collect();
1a4d82fc 1225
85aaf69f 1226 for x in &xs {
1a4d82fc
JJ
1227 assert!(set.contains(x));
1228 }
1229 }
1230
1231 #[test]
1232 fn test_move_iter() {
1233 let hs = {
1234 let mut hs = HashSet::new();
1235
1236 hs.insert('a');
1237 hs.insert('b');
1238
1239 hs
1240 };
1241
1242 let v = hs.into_iter().collect::<Vec<char>>();
c34b1796 1243 assert!(v == ['a', 'b'] || v == ['b', 'a']);
1a4d82fc
JJ
1244 }
1245
1246 #[test]
1247 fn test_eq() {
1248 // These constants once happened to expose a bug in insert().
1249 // I'm keeping them around to prevent a regression.
1250 let mut s1 = HashSet::new();
1251
85aaf69f 1252 s1.insert(1);
1a4d82fc
JJ
1253 s1.insert(2);
1254 s1.insert(3);
1255
1256 let mut s2 = HashSet::new();
1257
85aaf69f 1258 s2.insert(1);
1a4d82fc
JJ
1259 s2.insert(2);
1260
1261 assert!(s1 != s2);
1262
1263 s2.insert(3);
1264
1265 assert_eq!(s1, s2);
1266 }
1267
1268 #[test]
1269 fn test_show() {
85aaf69f
SL
1270 let mut set = HashSet::new();
1271 let empty = HashSet::<i32>::new();
1a4d82fc 1272
85aaf69f 1273 set.insert(1);
1a4d82fc
JJ
1274 set.insert(2);
1275
1276 let set_str = format!("{:?}", set);
1277
c34b1796
AL
1278 assert!(set_str == "{1, 2}" || set_str == "{2, 1}");
1279 assert_eq!(format!("{:?}", empty), "{}");
1a4d82fc
JJ
1280 }
1281
1282 #[test]
1283 fn test_trivial_drain() {
85aaf69f 1284 let mut s = HashSet::<i32>::new();
1a4d82fc
JJ
1285 for _ in s.drain() {}
1286 assert!(s.is_empty());
1287 drop(s);
1288
85aaf69f 1289 let mut s = HashSet::<i32>::new();
1a4d82fc
JJ
1290 drop(s.drain());
1291 assert!(s.is_empty());
1292 }
1293
1294 #[test]
1295 fn test_drain() {
85aaf69f 1296 let mut s: HashSet<_> = (1..100).collect();
1a4d82fc
JJ
1297
1298 // try this a bunch of times to make sure we don't screw up internal state.
85aaf69f 1299 for _ in 0..20 {
1a4d82fc
JJ
1300 assert_eq!(s.len(), 99);
1301
1302 {
1303 let mut last_i = 0;
1304 let mut d = s.drain();
1305 for (i, x) in d.by_ref().take(50).enumerate() {
1306 last_i = i;
1307 assert!(x != 0);
1308 }
1309 assert_eq!(last_i, 49);
1310 }
1311
85aaf69f 1312 for _ in &s { panic!("s should be empty!"); }
1a4d82fc
JJ
1313
1314 // reset to try again.
85aaf69f 1315 s.extend(1..100);
1a4d82fc
JJ
1316 }
1317 }
e9174d1e
SL
1318
1319 #[test]
1320 fn test_replace() {
1321 use hash;
1322
1323 #[derive(Debug)]
1324 struct Foo(&'static str, i32);
1325
1326 impl PartialEq for Foo {
1327 fn eq(&self, other: &Self) -> bool {
1328 self.0 == other.0
1329 }
1330 }
1331
1332 impl Eq for Foo {}
1333
1334 impl hash::Hash for Foo {
1335 fn hash<H: hash::Hasher>(&self, h: &mut H) {
1336 self.0.hash(h);
1337 }
1338 }
1339
1340 let mut s = HashSet::new();
1341 assert_eq!(s.replace(Foo("a", 1)), None);
1342 assert_eq!(s.len(), 1);
1343 assert_eq!(s.replace(Foo("a", 2)), Some(Foo("a", 1)));
1344 assert_eq!(s.len(), 1);
1345
1346 let mut it = s.iter();
1347 assert_eq!(it.next(), Some(&Foo("a", 2)));
1348 assert_eq!(it.next(), None);
1349 }
1350
1351 #[test]
1352 fn test_extend_ref() {
1353 let mut a = HashSet::new();
1354 a.insert(1);
1355
1356 a.extend(&[2, 3, 4]);
1357
1358 assert_eq!(a.len(), 4);
1359 assert!(a.contains(&1));
1360 assert!(a.contains(&2));
1361 assert!(a.contains(&3));
1362 assert!(a.contains(&4));
1363
1364 let mut b = HashSet::new();
1365 b.insert(5);
1366 b.insert(6);
1367
1368 a.extend(&b);
1369
1370 assert_eq!(a.len(), 6);
1371 assert!(a.contains(&1));
1372 assert!(a.contains(&2));
1373 assert!(a.contains(&3));
1374 assert!(a.contains(&4));
1375 assert!(a.contains(&5));
1376 assert!(a.contains(&6));
1377 }
1a4d82fc 1378}