rune_alloc/hashbrown/
set.rs

1use core::fmt;
2use core::hash::{BuildHasher, Hash};
3use core::iter::{Chain, FusedIterator};
4
5use super::Equivalent;
6
7use crate::alloc::{Allocator, Global};
8use crate::borrow::TryToOwned;
9use crate::clone::TryClone;
10use crate::error::Error;
11use crate::iter::{TryExtend, TryFromIteratorIn};
12#[cfg(test)]
13use crate::testing::*;
14
15use super::map::{self, DefaultHashBuilder, ExtractIfInner, HashMap, Keys};
16use super::raw::RawTable;
17
18// Future Optimization (FIXME!)
19// =============================
20//
21// Iteration over zero sized values is a noop. There is no need
22// for `bucket.val` in the case of HashSet. I suppose we would need HKT
23// to get rid of it properly.
24
25/// A hash set implemented as a `HashMap` where the value is `()`.
26///
27/// As with the [`HashMap`] type, a `HashSet` requires that the elements
28/// implement the [`Eq`] and [`Hash`] traits. This can frequently be achieved by
29/// using `#[derive(PartialEq, Eq, Hash)]`. If you implement these yourself,
30/// it is important that the following property holds:
31///
32/// ```text
33/// k1 == k2 -> hash(k1) == hash(k2)
34/// ```
35///
36/// In other words, if two keys are equal, their hashes must be equal.
37///
38///
39/// It is a logic error for an item to be modified in such a way that the
40/// item's hash, as determined by the [`Hash`] trait, or its equality, as
41/// determined by the [`Eq`] trait, changes while it is in the set. This is
42/// normally only possible through [`Cell`], [`RefCell`], global state, I/O, or
43/// unsafe code.
44///
45/// It is also a logic error for the [`Hash`] implementation of a key to panic.
46/// This is generally only possible if the trait is implemented manually. If a
47/// panic does occur then the contents of the `HashSet` may become corrupted and
48/// some items may be dropped from the table.
49///
50/// # Examples
51///
52/// ```
53/// use rune::alloc::HashSet;
54/// // Type inference lets us omit an explicit type signature (which
55/// // would be `HashSet<String>` in this example).
56/// let mut books = HashSet::new();
57///
58/// // Add some books.
59/// books.try_insert("A Dance With Dragons".to_string())?;
60/// books.try_insert("To Kill a Mockingbird".to_string())?;
61/// books.try_insert("The Odyssey".to_string())?;
62/// books.try_insert("The Great Gatsby".to_string())?;
63///
64/// // Check for a specific one.
65/// if !books.contains("The Winds of Winter") {
66///     println!("We have {} books, but The Winds of Winter ain't one.",
67///              books.len());
68/// }
69///
70/// // Remove a book.
71/// books.remove("The Odyssey");
72///
73/// // Iterate over everything.
74/// for book in &books {
75///     println!("{}", book);
76/// }
77/// # Ok::<_, rune::alloc::Error>(())
78/// ```
79///
80/// The easiest way to use `HashSet` with a custom type is to derive
81/// [`Eq`] and [`Hash`]. We must also derive [`PartialEq`]. This will in the
82/// future be implied by [`Eq`].
83///
84/// ```
85/// use rune::alloc::HashSet;
86///
87/// #[derive(Hash, Eq, PartialEq, Debug)]
88/// struct Viking {
89///     name: String,
90///     power: usize,
91/// }
92///
93/// let mut vikings = HashSet::new();
94///
95/// vikings.try_insert(Viking { name: "Einar".to_string(), power: 9 })?;
96/// vikings.try_insert(Viking { name: "Einar".to_string(), power: 9 })?;
97/// vikings.try_insert(Viking { name: "Olaf".to_string(), power: 4 })?;
98/// vikings.try_insert(Viking { name: "Harald".to_string(), power: 8 })?;
99///
100/// // Use derived implementation to print the vikings.
101/// for x in &vikings {
102///     println!("{:?}", x);
103/// }
104/// # Ok::<_, rune::alloc::Error>(())
105/// ```
106///
107/// A `HashSet` with fixed list of elements can be initialized from an array:
108///
109/// ```
110/// use rune::alloc::HashSet;
111/// use rune::alloc::prelude::*;
112///
113/// let viking_names: HashSet<&'static str> =
114///     [ "Einar", "Olaf", "Harald" ].iter().copied().try_collect()?;
115/// // use the values stored in the set
116/// # Ok::<_, rune::alloc::Error>(())
117/// ```
118///
119/// [`Cell`]: https://doc.rust-lang.org/std/cell/struct.Cell.html
120/// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
121/// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
122/// [`HashMap`]: struct.HashMap.html
123/// [`PartialEq`]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html
124/// [`RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html
125pub struct HashSet<T, S = DefaultHashBuilder, A: Allocator = Global> {
126    pub(crate) map: HashMap<T, (), S, A>,
127}
128
129impl<T, S, A: Allocator + Clone> TryClone for HashSet<T, S, A>
130where
131    T: TryClone,
132    S: Clone,
133{
134    fn try_clone(&self) -> Result<Self, Error> {
135        Ok(HashSet {
136            map: self.map.try_clone()?,
137        })
138    }
139
140    fn try_clone_from(&mut self, source: &Self) -> Result<(), Error> {
141        self.map.try_clone_from(&source.map)?;
142        Ok(())
143    }
144}
145
146#[cfg(test)]
147impl<T, S, A: Allocator + Clone> Clone for HashSet<T, S, A>
148where
149    T: TryClone,
150    S: Clone,
151{
152    fn clone(&self) -> Self {
153        self.try_clone().abort()
154    }
155
156    fn clone_from(&mut self, source: &Self) {
157        self.map.try_clone_from(&source.map).abort();
158    }
159}
160
161impl<T> HashSet<T, DefaultHashBuilder> {
162    /// Creates an empty `HashSet`.
163    ///
164    /// The hash set is initially created with a capacity of 0, so it will not allocate until it
165    /// is first inserted into.
166    ///
167    /// # HashDoS resistance
168    ///
169    /// The `hash_builder` normally use a fixed key by default and that does
170    /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
171    /// Users who require HashDoS resistance should explicitly use
172    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
173    /// as the hasher when creating a [`HashSet`], for example with
174    /// [`with_hasher`](HashSet::with_hasher) method.
175    ///
176    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
177    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
178    ///
179    /// # Examples
180    ///
181    /// ```
182    /// use rune::alloc::HashSet;
183    /// let set: HashSet<i32> = HashSet::new();
184    /// ```
185    #[cfg_attr(feature = "inline-more", inline)]
186    pub fn new() -> Self {
187        Self {
188            map: HashMap::new(),
189        }
190    }
191
192    /// Creates an empty `HashSet` with the specified capacity.
193    ///
194    /// The hash set will be able to hold at least `capacity` elements without
195    /// reallocating. If `capacity` is 0, the hash set will not allocate.
196    ///
197    /// # HashDoS resistance
198    ///
199    /// The `hash_builder` normally use a fixed key by default and that does not
200    /// allow the `HashSet` to be protected against attacks such as [`HashDoS`].
201    /// Users who require HashDoS resistance should explicitly use
202    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`] as
203    /// the hasher when creating a [`HashSet`], for example with
204    /// [`try_with_capacity_and_hasher`] method.
205    ///
206    /// [`try_with_capacity_and_hasher`]: HashSet::try_with_capacity_and_hasher
207    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
208    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
209    ///
210    /// # Examples
211    ///
212    /// ```
213    /// use rune::alloc::HashSet;
214    /// let set: HashSet<i32> = HashSet::try_with_capacity(10)?;
215    /// assert!(set.capacity() >= 10);
216    /// # Ok::<_, rune::alloc::Error>(())
217    /// ```
218    #[cfg_attr(feature = "inline-more", inline)]
219    pub fn try_with_capacity(capacity: usize) -> Result<Self, Error> {
220        Ok(Self {
221            map: HashMap::try_with_capacity(capacity)?,
222        })
223    }
224
225    #[cfg(test)]
226    pub(crate) fn with_capacity(capacity: usize) -> Self {
227        Self::try_with_capacity(capacity).abort()
228    }
229}
230
231impl<T: Hash + Eq, A: Allocator> HashSet<T, DefaultHashBuilder, A> {
232    /// Creates an empty `HashSet`.
233    ///
234    /// The hash set is initially created with a capacity of 0, so it will not allocate until it
235    /// is first inserted into.
236    ///
237    /// # HashDoS resistance
238    ///
239    /// The `hash_builder` normally use a fixed key by default and that does
240    /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
241    /// Users who require HashDoS resistance should explicitly use
242    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
243    /// as the hasher when creating a [`HashSet`], for example with
244    /// [`with_hasher_in`](HashSet::with_hasher_in) method.
245    ///
246    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
247    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
248    ///
249    /// # Examples
250    ///
251    /// ```
252    /// use rune::alloc::HashSet;
253    /// use rune::alloc::alloc::Global;
254    ///
255    /// let set: HashSet<i32> = HashSet::new_in(Global);
256    /// ```
257    #[cfg_attr(feature = "inline-more", inline)]
258    pub fn new_in(alloc: A) -> Self {
259        Self {
260            map: HashMap::new_in(alloc),
261        }
262    }
263
264    /// Creates an empty `HashSet` with the specified capacity.
265    ///
266    /// The hash set will be able to hold at least `capacity` elements without
267    /// reallocating. If `capacity` is 0, the hash set will not allocate.
268    ///
269    /// # HashDoS resistance
270    ///
271    /// The `hash_builder` normally use a fixed key by default and that does not
272    /// allow the `HashSet` to be protected against attacks such as [`HashDoS`].
273    /// Users who require HashDoS resistance should explicitly use
274    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`] as
275    /// the hasher when creating a [`HashSet`], for example with
276    /// [`try_with_capacity_and_hasher_in`] method.
277    ///
278    /// [`try_with_capacity_and_hasher_in`]:
279    ///     HashSet::try_with_capacity_and_hasher_in
280    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
281    /// [`std::collections::hash_map::RandomState`]:
282    ///     https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
283    ///
284    /// # Examples
285    ///
286    /// ```
287    /// use rune::alloc::HashSet;
288    /// let set: HashSet<i32> = HashSet::try_with_capacity(10)?;
289    /// assert!(set.capacity() >= 10);
290    /// # Ok::<_, rune::alloc::Error>(())
291    /// ```
292    #[cfg_attr(feature = "inline-more", inline)]
293    pub fn try_with_capacity_in(capacity: usize, alloc: A) -> Result<Self, Error> {
294        Ok(Self {
295            map: HashMap::try_with_capacity_in(capacity, alloc)?,
296        })
297    }
298}
299
300impl<T, S, A: Allocator> HashSet<T, S, A> {
301    /// Returns the number of elements the set can hold without reallocating.
302    ///
303    /// # Examples
304    ///
305    /// ```
306    /// use rune::alloc::HashSet;
307    ///
308    /// let set: HashSet<i32> = HashSet::try_with_capacity(100)?;
309    /// assert!(set.capacity() >= 100);
310    /// # Ok::<_, rune::alloc::Error>(())
311    /// ```
312    #[cfg_attr(feature = "inline-more", inline)]
313    pub fn capacity(&self) -> usize {
314        self.map.capacity()
315    }
316
317    /// An iterator visiting all elements in arbitrary order.
318    /// The iterator element type is `&'a T`.
319    ///
320    /// # Examples
321    ///
322    /// ```
323    /// use rune::alloc::HashSet;
324    ///
325    /// let mut set = HashSet::new();
326    /// set.try_insert("a")?;
327    /// set.try_insert("b")?;
328    ///
329    /// // Will print in an arbitrary order.
330    /// for x in set.iter() {
331    ///     println!("{}", x);
332    /// }
333    /// # Ok::<_, rune::alloc::Error>(())
334    /// ```
335    #[cfg_attr(feature = "inline-more", inline)]
336    pub fn iter(&self) -> Iter<'_, T> {
337        Iter {
338            iter: self.map.keys(),
339        }
340    }
341
342    /// Returns the number of elements in the set.
343    ///
344    /// # Examples
345    ///
346    /// ```
347    /// use rune::alloc::HashSet;
348    ///
349    /// let mut v = HashSet::new();
350    /// assert_eq!(v.len(), 0);
351    /// v.try_insert(1)?;
352    /// assert_eq!(v.len(), 1);
353    /// # Ok::<_, rune::alloc::Error>(())
354    /// ```
355    #[cfg_attr(feature = "inline-more", inline)]
356    pub fn len(&self) -> usize {
357        self.map.len()
358    }
359
360    /// Returns `true` if the set contains no elements.
361    ///
362    /// # Examples
363    ///
364    /// ```
365    /// use rune::alloc::HashSet;
366    ///
367    /// let mut v = HashSet::new();
368    /// assert!(v.is_empty());
369    /// v.try_insert(1)?;
370    /// assert!(!v.is_empty());
371    /// # Ok::<_, rune::alloc::Error>(())
372    /// ```
373    #[cfg_attr(feature = "inline-more", inline)]
374    pub fn is_empty(&self) -> bool {
375        self.map.is_empty()
376    }
377
378    /// Clears the set, returning all elements in an iterator.
379    ///
380    /// # Examples
381    ///
382    /// ```
383    /// use rune::alloc::HashSet;
384    ///
385    /// let mut set: HashSet<_> = HashSet::try_from([1, 2, 3])?;
386    /// assert!(!set.is_empty());
387    ///
388    /// // print 1, 2, 3 in an arbitrary order
389    /// for i in set.drain() {
390    ///     println!("{}", i);
391    /// }
392    ///
393    /// assert!(set.is_empty());
394    /// # Ok::<_, rune::alloc::Error>(())
395    /// ```
396    #[cfg_attr(feature = "inline-more", inline)]
397    pub fn drain(&mut self) -> Drain<'_, T, A> {
398        Drain {
399            iter: self.map.drain(),
400        }
401    }
402
403    /// Retains only the elements specified by the predicate.
404    ///
405    /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
406    ///
407    /// # Examples
408    ///
409    /// ```
410    /// use rune::alloc::HashSet;
411    ///
412    /// let mut set: HashSet<i32> = HashSet::try_from([1, 2, 3, 4, 5, 6])?;
413    /// set.retain(|&k| k % 2 == 0);
414    /// assert_eq!(set.len(), 3);
415    /// # Ok::<_, rune::alloc::Error>(())
416    /// ```
417    pub fn retain<F>(&mut self, mut f: F)
418    where
419        F: FnMut(&T) -> bool,
420    {
421        self.map.retain(|k, _| f(k));
422    }
423
424    /// Drains elements which are true under the given predicate, and returns an
425    /// iterator over the removed items.
426    ///
427    /// In other words, move all elements `e` such that `f(&e)` returns `true`
428    /// out into another iterator.
429    ///
430    /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped
431    /// without iterating or the iteration short-circuits, then the remaining
432    /// elements will be retained. Use [`retain`] with a negated predicate if
433    /// you do not need the returned iterator.
434    ///
435    /// [`retain`]: Self::retain
436    ///
437    /// # Examples
438    ///
439    /// ```
440    /// use rune::alloc::{try_vec, HashSet, Vec};
441    /// use rune::alloc::prelude::*;
442    ///
443    /// let mut set: HashSet<i32> = (0..8).try_collect()?;
444    /// let drained: HashSet<i32> = set.extract_if(|v| v % 2 == 0).try_collect()?;
445    ///
446    /// let mut evens = drained.into_iter().try_collect::<Vec<_>>()?;
447    /// let mut odds = set.into_iter().try_collect::<Vec<_>>()?;
448    /// evens.sort();
449    /// odds.sort();
450    ///
451    /// assert_eq!(evens, try_vec![0, 2, 4, 6]);
452    /// assert_eq!(odds, try_vec![1, 3, 5, 7]);
453    /// # Ok::<_, rune::alloc::Error>(())
454    /// ```
455    #[cfg_attr(feature = "inline-more", inline)]
456    pub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, T, F, A>
457    where
458        F: FnMut(&T) -> bool,
459    {
460        ExtractIf {
461            f,
462            inner: ExtractIfInner {
463                iter: unsafe { self.map.table.iter() },
464                table: &mut self.map.table,
465            },
466        }
467    }
468
469    /// Clears the set, removing all values.
470    ///
471    /// # Examples
472    ///
473    /// ```
474    /// use rune::alloc::HashSet;
475    ///
476    /// let mut v = HashSet::new();
477    /// v.try_insert(1)?;
478    /// v.clear();
479    /// assert!(v.is_empty());
480    /// # Ok::<_, rune::alloc::Error>(())
481    /// ```
482    #[cfg_attr(feature = "inline-more", inline)]
483    pub fn clear(&mut self) {
484        self.map.clear();
485    }
486}
487
488impl<T, S> HashSet<T, S, Global> {
489    /// Creates a new empty hash set which will use the given hasher to hash
490    /// keys.
491    ///
492    /// The hash set is initially created with a capacity of 0, so it will not
493    /// allocate until it is first inserted into.
494    ///
495    /// # HashDoS resistance
496    ///
497    /// The `hash_builder` normally use a fixed key by default and that does
498    /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
499    /// Users who require HashDoS resistance should explicitly use
500    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
501    /// as the hasher when creating a [`HashSet`].
502    ///
503    /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
504    /// the HashSet to be useful, see its documentation for details.
505    ///
506    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
507    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
508    /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
509    ///
510    /// # Examples
511    ///
512    /// ```
513    /// use rune::alloc::HashSet;
514    /// use rune::alloc::hash_map::DefaultHashBuilder;
515    ///
516    /// let s = DefaultHashBuilder::default();
517    /// let mut set = HashSet::with_hasher(s);
518    /// set.try_insert(2)?;
519    /// # Ok::<_, rune::alloc::Error>(())
520    /// ```
521    #[cfg_attr(feature = "inline-more", inline)]
522    pub const fn with_hasher(hasher: S) -> Self {
523        Self {
524            map: HashMap::with_hasher(hasher),
525        }
526    }
527
528    /// Creates an empty `HashSet` with the specified capacity, using
529    /// `hasher` to hash the keys.
530    ///
531    /// The hash set will be able to hold at least `capacity` elements without
532    /// reallocating. If `capacity` is 0, the hash set will not allocate.
533    ///
534    /// # HashDoS resistance
535    ///
536    /// The `hash_builder` normally use a fixed key by default and that does
537    /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
538    /// Users who require HashDoS resistance should explicitly use
539    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
540    /// as the hasher when creating a [`HashSet`].
541    ///
542    /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
543    /// the HashSet to be useful, see its documentation for details.
544    ///
545    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
546    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
547    /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
548    ///
549    /// # Examples
550    ///
551    /// ```
552    /// use rune::alloc::HashSet;
553    /// use rune::alloc::hash_map::DefaultHashBuilder;
554    ///
555    /// let s = DefaultHashBuilder::default();
556    /// let mut set = HashSet::try_with_capacity_and_hasher(10, s)?;
557    /// set.try_insert(1)?;
558    /// # Ok::<_, rune::alloc::Error>(())
559    /// ```
560    #[cfg_attr(feature = "inline-more", inline)]
561    pub fn try_with_capacity_and_hasher(capacity: usize, hasher: S) -> Result<Self, Error> {
562        Ok(Self {
563            map: HashMap::try_with_capacity_and_hasher(capacity, hasher)?,
564        })
565    }
566
567    #[cfg(test)]
568    pub(crate) fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self {
569        Self::try_with_capacity_and_hasher(capacity, hasher).abort()
570    }
571}
572
573impl<T, S, A> HashSet<T, S, A>
574where
575    A: Allocator,
576{
577    /// Returns a reference to the underlying allocator.
578    #[inline]
579    pub fn allocator(&self) -> &A {
580        self.map.allocator()
581    }
582
583    /// Creates a new empty hash set which will use the given hasher to hash
584    /// keys.
585    ///
586    /// The hash set is initially created with a capacity of 0, so it will not
587    /// allocate until it is first inserted into.
588    ///
589    /// # HashDoS resistance
590    ///
591    /// The `hash_builder` normally use a fixed key by default and that does
592    /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
593    /// Users who require HashDoS resistance should explicitly use
594    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
595    /// as the hasher when creating a [`HashSet`].
596    ///
597    /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
598    /// the HashSet to be useful, see its documentation for details.
599    ///
600    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
601    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
602    /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
603    ///
604    /// # Examples
605    ///
606    /// ```
607    /// use rune::alloc::HashSet;
608    /// use rune::alloc::hash_map::DefaultHashBuilder;
609    ///
610    /// let s = DefaultHashBuilder::default();
611    /// let mut set = HashSet::with_hasher(s);
612    /// set.try_insert(2)?;
613    /// # Ok::<_, rune::alloc::Error>(())
614    /// ```
615    #[cfg_attr(feature = "inline-more", inline)]
616    pub const fn with_hasher_in(hasher: S, alloc: A) -> Self {
617        Self {
618            map: HashMap::with_hasher_in(hasher, alloc),
619        }
620    }
621
622    /// Creates an empty `HashSet` with the specified capacity, using
623    /// `hasher` to hash the keys.
624    ///
625    /// The hash set will be able to hold at least `capacity` elements without
626    /// reallocating. If `capacity` is 0, the hash set will not allocate.
627    ///
628    /// # HashDoS resistance
629    ///
630    /// The `hash_builder` normally use a fixed key by default and that does
631    /// not allow the `HashSet` to be protected against attacks such as [`HashDoS`].
632    /// Users who require HashDoS resistance should explicitly use
633    /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
634    /// as the hasher when creating a [`HashSet`].
635    ///
636    /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
637    /// the HashSet to be useful, see its documentation for details.
638    ///
639    /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
640    /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
641    /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
642    ///
643    /// # Examples
644    ///
645    /// ```
646    /// use rune::alloc::HashSet;
647    /// use rune::alloc::alloc::Global;
648    /// use rune::alloc::hash_map::DefaultHashBuilder;
649    ///
650    /// let s = DefaultHashBuilder::default();
651    /// let mut set = HashSet::try_with_capacity_and_hasher_in(10, s, Global)?;
652    /// set.try_insert(1)?;
653    /// # Ok::<_, rune::alloc::Error>(())
654    /// ```
655    #[cfg_attr(feature = "inline-more", inline)]
656    pub fn try_with_capacity_and_hasher_in(
657        capacity: usize,
658        hasher: S,
659        alloc: A,
660    ) -> Result<Self, Error> {
661        Ok(Self {
662            map: HashMap::try_with_capacity_and_hasher_in(capacity, hasher, alloc)?,
663        })
664    }
665
666    /// Returns a reference to the set's [`BuildHasher`].
667    ///
668    /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
669    ///
670    /// # Examples
671    ///
672    /// ```
673    /// use rune::alloc::HashSet;
674    /// use rune::alloc::hash_map::DefaultHashBuilder;
675    ///
676    /// let hasher = DefaultHashBuilder::default();
677    /// let set: HashSet<i32> = HashSet::with_hasher(hasher);
678    /// let hasher: &DefaultHashBuilder = set.hasher();
679    /// ```
680    #[cfg_attr(feature = "inline-more", inline)]
681    pub fn hasher(&self) -> &S {
682        self.map.hasher()
683    }
684}
685
686impl<T, S, A> HashSet<T, S, A>
687where
688    T: Eq + Hash,
689    S: BuildHasher,
690    A: Allocator,
691{
692    /// Tries to reserve capacity for at least `additional` more elements to be inserted
693    /// in the given `HashSet<K,V>`. The collection may reserve more space to avoid
694    /// frequent reallocations.
695    ///
696    /// # Errors
697    ///
698    /// If the capacity overflows, or the allocator reports a failure, then an error
699    /// is returned.
700    ///
701    /// # Examples
702    ///
703    /// ```
704    /// use rune::alloc::HashSet;
705    /// let mut set: HashSet<i32> = HashSet::new();
706    /// set.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?");
707    /// ```
708    #[cfg_attr(feature = "inline-more", inline)]
709    pub fn try_reserve(&mut self, additional: usize) -> Result<(), Error> {
710        self.map.try_reserve(additional)
711    }
712
713    #[cfg(test)]
714    pub(crate) fn reserve(&mut self, additional: usize) {
715        self.try_reserve(additional).abort()
716    }
717
718    /// Shrinks the capacity of the set as much as possible. It will drop
719    /// down as much as possible while maintaining the internal rules
720    /// and possibly leaving some space in accordance with the resize policy.
721    ///
722    /// # Examples
723    ///
724    /// ```
725    /// use rune::alloc::HashSet;
726    ///
727    /// let mut set = HashSet::try_with_capacity(100)?;
728    /// set.try_insert(1)?;
729    /// set.try_insert(2)?;
730    /// assert!(set.capacity() >= 100);
731    /// set.try_shrink_to_fit()?;
732    /// assert!(set.capacity() >= 2);
733    /// # Ok::<_, rune::alloc::Error>(())
734    /// ```
735    #[cfg_attr(feature = "inline-more", inline)]
736    pub fn try_shrink_to_fit(&mut self) -> Result<(), Error> {
737        self.map.try_shrink_to_fit()
738    }
739
740    #[cfg(test)]
741    pub(crate) fn shrink_to_fit(&mut self) {
742        self.try_shrink_to_fit().abort();
743    }
744
745    /// Shrinks the capacity of the set with a lower limit. It will drop
746    /// down no lower than the supplied limit while maintaining the internal rules
747    /// and possibly leaving some space in accordance with the resize policy.
748    ///
749    /// Panics if the current capacity is smaller than the supplied
750    /// minimum capacity.
751    ///
752    /// # Examples
753    ///
754    /// ```
755    /// use rune::alloc::HashSet;
756    ///
757    /// let mut set = HashSet::try_with_capacity(100)?;
758    /// set.try_insert(1)?;
759    /// set.try_insert(2)?;
760    /// assert!(set.capacity() >= 100);
761    /// set.try_shrink_to(10)?;
762    /// assert!(set.capacity() >= 10);
763    /// set.try_shrink_to(0)?;
764    /// assert!(set.capacity() >= 2);
765    /// # Ok::<_, rune::alloc::Error>(())
766    /// ```
767    #[cfg_attr(feature = "inline-more", inline)]
768    pub fn try_shrink_to(&mut self, min_capacity: usize) -> Result<(), Error> {
769        self.map.try_shrink_to(min_capacity)
770    }
771
772    /// Visits the values representing the difference,
773    /// i.e., the values that are in `self` but not in `other`.
774    ///
775    /// # Examples
776    ///
777    /// ```
778    /// use rune::alloc::HashSet;
779    /// use rune::alloc::prelude::*;
780    ///
781    /// let a: HashSet<_> = HashSet::try_from([1, 2, 3])?;
782    /// let b: HashSet<_> = HashSet::try_from([4, 2, 3, 4])?;
783    ///
784    /// // Can be seen as `a - b`.
785    /// for x in a.difference(&b) {
786    ///     println!("{}", x); // Print 1
787    /// }
788    ///
789    /// let diff: HashSet<_> = a.difference(&b).copied().try_collect()?;
790    /// assert_eq!(diff, HashSet::try_from([1])?);
791    ///
792    /// // Note that difference is not symmetric,
793    /// // and `b - a` means something else:
794    /// let diff: HashSet<_> = b.difference(&a).copied().try_collect()?;
795    /// assert_eq!(diff, HashSet::try_from([4])?);
796    /// # Ok::<_, rune::alloc::Error>(())
797    /// ```
798    #[cfg_attr(feature = "inline-more", inline)]
799    pub fn difference<'a>(&'a self, other: &'a Self) -> Difference<'a, T, S, A> {
800        Difference {
801            iter: self.iter(),
802            other,
803        }
804    }
805
806    /// Visits the values representing the symmetric difference,
807    /// i.e., the values that are in `self` or in `other` but not in both.
808    ///
809    /// # Examples
810    ///
811    /// ```
812    /// use rune::alloc::HashSet;
813    /// use rune::alloc::prelude::*;
814    ///
815    /// let a: HashSet<_> = HashSet::try_from([1, 2, 3])?;
816    /// let b: HashSet<_> = HashSet::try_from([4, 2, 3, 4])?;
817    ///
818    /// // Print 1, 4 in arbitrary order.
819    /// for x in a.symmetric_difference(&b) {
820    ///     println!("{}", x);
821    /// }
822    ///
823    /// let diff1: HashSet<_> = a.symmetric_difference(&b).copied().try_collect()?;
824    /// let diff2: HashSet<_> = b.symmetric_difference(&a).copied().try_collect()?;
825    ///
826    /// assert_eq!(diff1, diff2);
827    /// assert_eq!(diff1, HashSet::try_from([1, 4])?);
828    /// # Ok::<_, rune::alloc::Error>(())
829    /// ```
830    #[cfg_attr(feature = "inline-more", inline)]
831    pub fn symmetric_difference<'a>(&'a self, other: &'a Self) -> SymmetricDifference<'a, T, S, A> {
832        SymmetricDifference {
833            iter: self.difference(other).chain(other.difference(self)),
834        }
835    }
836
837    /// Visits the values representing the intersection,
838    /// i.e., the values that are both in `self` and `other`.
839    ///
840    /// # Examples
841    ///
842    /// ```
843    /// use rune::alloc::HashSet;
844    /// use rune::alloc::prelude::*;
845    ///
846    /// let a: HashSet<_> = HashSet::try_from([1, 2, 3])?;
847    /// let b: HashSet<_> = HashSet::try_from([4, 2, 3, 4])?;
848    ///
849    /// // Print 2, 3 in arbitrary order.
850    /// for x in a.intersection(&b) {
851    ///     println!("{}", x);
852    /// }
853    ///
854    /// let intersection: HashSet<_> = a.intersection(&b).copied().try_collect()?;
855    /// assert_eq!(intersection, HashSet::try_from([2, 3])?);
856    /// # Ok::<_, rune::alloc::Error>(())
857    /// ```
858    #[cfg_attr(feature = "inline-more", inline)]
859    pub fn intersection<'a>(&'a self, other: &'a Self) -> Intersection<'a, T, S, A> {
860        let (smaller, larger) = if self.len() <= other.len() {
861            (self, other)
862        } else {
863            (other, self)
864        };
865        Intersection {
866            iter: smaller.iter(),
867            other: larger,
868        }
869    }
870
871    /// Visits the values representing the union,
872    /// i.e., all the values in `self` or `other`, without duplicates.
873    ///
874    /// # Examples
875    ///
876    /// ```
877    /// use rune::alloc::HashSet;
878    /// use rune::alloc::prelude::*;
879    ///
880    /// let a: HashSet<_> = HashSet::try_from([1, 2, 3])?;
881    /// let b: HashSet<_> = HashSet::try_from([4, 2, 3, 4])?;
882    ///
883    /// // Print 1, 2, 3, 4 in arbitrary order.
884    /// for x in a.union(&b) {
885    ///     println!("{}", x);
886    /// }
887    ///
888    /// let union: HashSet<_> = a.union(&b).copied().try_collect()?;
889    /// assert_eq!(union, HashSet::try_from([1, 2, 3, 4])?);
890    /// # Ok::<_, rune::alloc::Error>(())
891    /// ```
892    #[cfg_attr(feature = "inline-more", inline)]
893    pub fn union<'a>(&'a self, other: &'a Self) -> Union<'a, T, S, A> {
894        // We'll iterate one set in full, and only the remaining difference from the other.
895        // Use the smaller set for the difference in order to reduce hash lookups.
896        let (smaller, larger) = if self.len() <= other.len() {
897            (self, other)
898        } else {
899            (other, self)
900        };
901        Union {
902            iter: larger.iter().chain(smaller.difference(larger)),
903        }
904    }
905
906    /// Returns `true` if the set contains a value.
907    ///
908    /// The value may be any borrowed form of the set's value type, but
909    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
910    /// the value type.
911    ///
912    /// # Examples
913    ///
914    /// ```
915    /// use rune::alloc::HashSet;
916    ///
917    /// let set: HashSet<_> = HashSet::try_from([1, 2, 3])?;
918    /// assert_eq!(set.contains(&1), true);
919    /// assert_eq!(set.contains(&4), false);
920    /// # Ok::<_, rune::alloc::Error>(())
921    /// ```
922    ///
923    /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
924    /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
925    #[cfg_attr(feature = "inline-more", inline)]
926    pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
927    where
928        Q: Hash + Equivalent<T>,
929    {
930        self.map.contains_key(value)
931    }
932
933    /// Returns a reference to the value in the set, if any, that is equal to the given value.
934    ///
935    /// The value may be any borrowed form of the set's value type, but
936    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
937    /// the value type.
938    ///
939    /// # Examples
940    ///
941    /// ```
942    /// use rune::alloc::HashSet;
943    ///
944    /// let set: HashSet<_> = HashSet::try_from([1, 2, 3])?;
945    /// assert_eq!(set.get(&2), Some(&2));
946    /// assert_eq!(set.get(&4), None);
947    /// # Ok::<_, rune::alloc::Error>(())
948    /// ```
949    ///
950    /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
951    /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
952    #[cfg_attr(feature = "inline-more", inline)]
953    pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T>
954    where
955        Q: Hash + Equivalent<T>,
956    {
957        // Avoid `Option::map` because it bloats LLVM IR.
958        match self.map.get_key_value(value) {
959            Some((k, _)) => Some(k),
960            None => None,
961        }
962    }
963
964    /// Inserts the given `value` into the set if it is not present, then
965    /// returns a reference to the value in the set.
966    ///
967    /// # Examples
968    ///
969    /// ```
970    /// use rune::alloc::HashSet;
971    ///
972    /// let mut set: HashSet<_> = HashSet::try_from([1, 2, 3])?;
973    /// assert_eq!(set.len(), 3);
974    /// assert_eq!(set.get_or_try_insert(2)?, &2);
975    /// assert_eq!(set.get_or_try_insert(100)?, &100);
976    /// assert_eq!(set.len(), 4); // 100 was inserted
977    /// # Ok::<_, rune::alloc::Error>(())
978    /// ```
979    #[cfg_attr(feature = "inline-more", inline)]
980    pub fn get_or_try_insert(&mut self, value: T) -> Result<&T, Error> {
981        // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with
982        // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`.
983        Ok(self
984            .map
985            .raw_entry_mut()
986            .from_key(&value)
987            .or_try_insert(value, ())?
988            .0)
989    }
990
991    /// Inserts an owned copy of the given `value` into the set if it is not
992    /// present, then returns a reference to the value in the set.
993    ///
994    /// # Examples
995    ///
996    /// ```
997    /// use rune::alloc::{HashSet, String, Error};
998    /// use rune::alloc::prelude::*;
999    ///
1000    /// let mut set: HashSet<String> = ["cat", "dog", "horse"]
1001    ///     .iter().map(|&pet| pet.try_to_owned()).try_collect::<Result<_, _>>()??;
1002    ///
1003    /// assert_eq!(set.len(), 3);
1004    /// for &pet in &["cat", "dog", "fish"] {
1005    ///     let value = set.get_or_try_insert_owned(pet)?;
1006    ///     assert_eq!(value, pet);
1007    /// }
1008    /// assert_eq!(set.len(), 4); // a new "fish" was inserted
1009    /// # Ok::<_, rune::alloc::Error>(())
1010    /// ```
1011    #[inline]
1012    pub fn get_or_try_insert_owned<Q: ?Sized>(&mut self, value: &Q) -> Result<&T, Error>
1013    where
1014        Q: Hash + Equivalent<T> + TryToOwned<Owned = T>,
1015    {
1016        // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with
1017        // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`.
1018        let (key, _) = match self.map.raw_entry_mut().from_key(value) {
1019            map::RawEntryMut::Occupied(entry) => entry.into_key_value(),
1020            map::RawEntryMut::Vacant(entry) => entry.try_insert(value.try_to_owned()?, ())?,
1021        };
1022
1023        Ok(key)
1024    }
1025
1026    /// Inserts a value computed from `f` into the set if the given `value` is
1027    /// not present, then returns a reference to the value in the set.
1028    ///
1029    /// # Examples
1030    ///
1031    /// ```
1032    /// use rune::alloc::{HashSet, String, Error};
1033    /// use rune::alloc::prelude::*;
1034    ///
1035    /// let mut set: HashSet<String> = ["cat", "dog", "horse"]
1036    ///     .iter().map(|&pet| pet.try_to_owned()).try_collect::<Result<_, _>>()??;
1037    ///
1038    /// assert_eq!(set.len(), 3);
1039    /// for &pet in &["cat", "dog", "fish"] {
1040    ///     let value = set.get_or_try_insert_with(pet, str::try_to_owned)?;
1041    ///     assert_eq!(value, pet);
1042    /// }
1043    /// assert_eq!(set.len(), 4); // a new "fish" was inserted
1044    /// # Ok::<_, rune::alloc::Error>(())
1045    /// ```
1046    #[cfg_attr(feature = "inline-more", inline)]
1047    pub fn get_or_try_insert_with<Q: ?Sized, F>(&mut self, value: &Q, f: F) -> Result<&T, Error>
1048    where
1049        Q: Hash + Equivalent<T>,
1050        F: FnOnce(&Q) -> Result<T, Error>,
1051    {
1052        // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with
1053        // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`.
1054        let (key, _) = match self.map.raw_entry_mut().from_key(value) {
1055            map::RawEntryMut::Occupied(entry) => entry.into_key_value(),
1056            map::RawEntryMut::Vacant(entry) => entry.try_insert(f(value)?, ())?,
1057        };
1058
1059        Ok(key)
1060    }
1061
1062    /// Gets the given value's corresponding entry in the set for in-place manipulation.
1063    ///
1064    /// # Examples
1065    ///
1066    /// ```
1067    /// use rune::alloc::HashSet;
1068    /// use rune::alloc::hash_set::Entry::*;
1069    ///
1070    /// let mut singles = HashSet::new();
1071    /// let mut dupes = HashSet::new();
1072    ///
1073    /// for ch in "a short treatise on fungi".chars() {
1074    ///     if let Vacant(dupe_entry) = dupes.entry(ch) {
1075    ///         // We haven't already seen a duplicate, so
1076    ///         // check if we've at least seen it once.
1077    ///         match singles.entry(ch) {
1078    ///             Vacant(single_entry) => {
1079    ///                 // We found a new character for the first time.
1080    ///                 single_entry.try_insert()?;
1081    ///             }
1082    ///             Occupied(single_entry) => {
1083    ///                 // We've already seen this once, "move" it to dupes.
1084    ///                 single_entry.remove();
1085    ///                 dupe_entry.try_insert()?;
1086    ///             }
1087    ///         }
1088    ///     }
1089    /// }
1090    ///
1091    /// assert!(!singles.contains(&'t') && dupes.contains(&'t'));
1092    /// assert!(singles.contains(&'u') && !dupes.contains(&'u'));
1093    /// assert!(!singles.contains(&'v') && !dupes.contains(&'v'));
1094    /// # Ok::<_, rune::alloc::Error>(())
1095    /// ```
1096    #[cfg_attr(feature = "inline-more", inline)]
1097    pub fn entry(&mut self, value: T) -> Entry<'_, T, S, A> {
1098        match self.map.entry(value) {
1099            map::Entry::Occupied(entry) => Entry::Occupied(OccupiedEntry { inner: entry }),
1100            map::Entry::Vacant(entry) => Entry::Vacant(VacantEntry { inner: entry }),
1101        }
1102    }
1103
1104    /// Returns `true` if `self` has no elements in common with `other`.
1105    /// This is equivalent to checking for an empty intersection.
1106    ///
1107    /// # Examples
1108    ///
1109    /// ```
1110    /// use rune::alloc::HashSet;
1111    ///
1112    /// let a = HashSet::try_from([1, 2, 3])?;
1113    /// let mut b = HashSet::new();
1114    ///
1115    /// assert_eq!(a.is_disjoint(&b), true);
1116    /// b.try_insert(4)?;
1117    /// assert_eq!(a.is_disjoint(&b), true);
1118    /// b.try_insert(1)?;
1119    /// assert_eq!(a.is_disjoint(&b), false);
1120    /// # Ok::<_, rune::alloc::Error>(())
1121    /// ```
1122    pub fn is_disjoint(&self, other: &Self) -> bool {
1123        self.iter().all(|v| !other.contains(v))
1124    }
1125
1126    /// Returns `true` if the set is a subset of another,
1127    /// i.e., `other` contains at least all the values in `self`.
1128    ///
1129    /// # Examples
1130    ///
1131    /// ```
1132    /// use rune::alloc::HashSet;
1133    ///
1134    /// let sup = HashSet::try_from([1, 2, 3])?;
1135    /// let mut set = HashSet::new();
1136    ///
1137    /// assert_eq!(set.is_subset(&sup), true);
1138    /// set.try_insert(2)?;
1139    /// assert_eq!(set.is_subset(&sup), true);
1140    /// set.try_insert(4)?;
1141    /// assert_eq!(set.is_subset(&sup), false);
1142    /// # Ok::<_, rune::alloc::Error>(())
1143    /// ```
1144    pub fn is_subset(&self, other: &Self) -> bool {
1145        self.len() <= other.len() && self.iter().all(|v| other.contains(v))
1146    }
1147
1148    /// Returns `true` if the set is a superset of another,
1149    /// i.e., `self` contains at least all the values in `other`.
1150    ///
1151    /// # Examples
1152    ///
1153    /// ```
1154    /// use rune::alloc::HashSet;
1155    ///
1156    /// let sub = HashSet::try_from([1, 2])?;
1157    /// let mut set = HashSet::new();
1158    ///
1159    /// assert_eq!(set.is_superset(&sub), false);
1160    ///
1161    /// set.try_insert(0)?;
1162    /// set.try_insert(1)?;
1163    /// assert_eq!(set.is_superset(&sub), false);
1164    ///
1165    /// set.try_insert(2)?;
1166    /// assert_eq!(set.is_superset(&sub), true);
1167    /// # Ok::<_, rune::alloc::Error>(())
1168    /// ```
1169    #[cfg_attr(feature = "inline-more", inline)]
1170    pub fn is_superset(&self, other: &Self) -> bool {
1171        other.is_subset(self)
1172    }
1173
1174    /// Adds a value to the set.
1175    ///
1176    /// If the set did not have this value present, `true` is returned.
1177    ///
1178    /// If the set did have this value present, `false` is returned.
1179    ///
1180    /// # Examples
1181    ///
1182    /// ```
1183    /// use rune::alloc::HashSet;
1184    ///
1185    /// let mut set = HashSet::new();
1186    ///
1187    /// assert_eq!(set.try_insert(2)?, true);
1188    /// assert_eq!(set.try_insert(2)?, false);
1189    /// assert_eq!(set.len(), 1);
1190    /// # Ok::<_, rune::alloc::Error>(())
1191    /// ```
1192    #[cfg_attr(feature = "inline-more", inline)]
1193    pub fn try_insert(&mut self, value: T) -> Result<bool, Error> {
1194        Ok(self.map.try_insert(value, ())?.is_none())
1195    }
1196
1197    #[cfg(test)]
1198    pub(crate) fn insert(&mut self, value: T) -> bool {
1199        self.try_insert(value).abort()
1200    }
1201
1202    /// Insert a value the set without checking if the value already exists in the set.
1203    ///
1204    /// Returns a reference to the value just inserted.
1205    ///
1206    /// This operation is safe if a value does not exist in the set.
1207    ///
1208    /// However, if a value exists in the set already, the behavior is unspecified:
1209    /// this operation may panic, loop forever, or any following operation with the set
1210    /// may panic, loop forever or return arbitrary result.
1211    ///
1212    /// That said, this operation (and following operations) are guaranteed to
1213    /// not violate memory safety.
1214    ///
1215    /// This operation is faster than regular insert, because it does not perform
1216    /// lookup before insertion.
1217    ///
1218    /// This operation is useful during initial population of the set.
1219    /// For example, when constructing a set from another set, we know
1220    /// that values are unique.
1221    #[cfg_attr(feature = "inline-more", inline)]
1222    pub fn try_insert_unique_unchecked(&mut self, value: T) -> Result<&T, Error> {
1223        Ok(self.map.try_insert_unique_unchecked(value, ())?.0)
1224    }
1225
1226    /// Adds a value to the set, replacing the existing value, if any, that is equal to the given
1227    /// one. Returns the replaced value.
1228    ///
1229    /// # Examples
1230    ///
1231    /// ```
1232    /// use rune::alloc::HashSet;
1233    ///
1234    /// let mut set = HashSet::new();
1235    /// set.try_insert(Vec::<i32>::new())?;
1236    ///
1237    /// assert_eq!(set.get(&[][..]).unwrap().capacity(), 0);
1238    /// set.try_replace(Vec::with_capacity(10))?;
1239    /// assert_eq!(set.get(&[][..]).unwrap().capacity(), 10);
1240    /// # Ok::<_, rune::alloc::Error>(())
1241    /// ```
1242    #[cfg_attr(feature = "inline-more", inline)]
1243    pub fn try_replace(&mut self, value: T) -> Result<Option<T>, Error> {
1244        match self.map.entry(value) {
1245            map::Entry::Occupied(occupied) => Ok(Some(occupied.replace_key())),
1246            map::Entry::Vacant(vacant) => {
1247                vacant.try_insert(())?;
1248                Ok(None)
1249            }
1250        }
1251    }
1252
1253    #[cfg(test)]
1254    pub(crate) fn replace(&mut self, value: T) -> Option<T> {
1255        self.try_replace(value).abort()
1256    }
1257
1258    /// Removes a value from the set. Returns whether the value was
1259    /// present in the set.
1260    ///
1261    /// The value may be any borrowed form of the set's value type, but
1262    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1263    /// the value type.
1264    ///
1265    /// # Examples
1266    ///
1267    /// ```
1268    /// use rune::alloc::HashSet;
1269    ///
1270    /// let mut set = HashSet::new();
1271    ///
1272    /// set.try_insert(2)?;
1273    /// assert_eq!(set.remove(&2), true);
1274    /// assert_eq!(set.remove(&2), false);
1275    /// # Ok::<_, rune::alloc::Error>(())
1276    /// ```
1277    ///
1278    /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1279    /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1280    #[cfg_attr(feature = "inline-more", inline)]
1281    pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
1282    where
1283        Q: Hash + Equivalent<T>,
1284    {
1285        self.map.remove(value).is_some()
1286    }
1287
1288    /// Removes and returns the value in the set, if any, that is equal to the given one.
1289    ///
1290    /// The value may be any borrowed form of the set's value type, but
1291    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1292    /// the value type.
1293    ///
1294    /// # Examples
1295    ///
1296    /// ```
1297    /// use rune::alloc::HashSet;
1298    ///
1299    /// let mut set: HashSet<_> = HashSet::try_from([1, 2, 3])?;
1300    /// assert_eq!(set.take(&2), Some(2));
1301    /// assert_eq!(set.take(&2), None);
1302    /// # Ok::<_, rune::alloc::Error>(())
1303    /// ```
1304    ///
1305    /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1306    /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1307    #[cfg_attr(feature = "inline-more", inline)]
1308    pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T>
1309    where
1310        Q: Hash + Equivalent<T>,
1311    {
1312        // Avoid `Option::map` because it bloats LLVM IR.
1313        match self.map.remove_entry(value) {
1314            Some((k, _)) => Some(k),
1315            None => None,
1316        }
1317    }
1318}
1319
1320impl<T, S, A: Allocator> HashSet<T, S, A> {
1321    /// Returns a reference to the [`RawTable`] used underneath [`HashSet`].
1322    /// This function is only available if the `raw` feature of the crate is enabled.
1323    ///
1324    /// # Note
1325    ///
1326    /// Calling this function is safe, but using the raw hash table API may require
1327    /// unsafe functions or blocks.
1328    ///
1329    /// `RawTable` API gives the lowest level of control under the set that can be useful
1330    /// for extending the HashSet's API, but may lead to *[undefined behavior]*.
1331    ///
1332    /// [`RawTable`]: crate::hashbrown::raw::RawTable
1333    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1334    #[cfg_attr(feature = "inline-more", inline)]
1335    pub fn raw_table(&self) -> &RawTable<(T, ()), A> {
1336        self.map.raw_table()
1337    }
1338
1339    /// Returns a mutable reference to the [`RawTable`] used underneath
1340    /// [`HashSet`]. This function is only available if the `raw` feature of the
1341    /// crate is enabled.
1342    ///
1343    /// # Note
1344    ///
1345    /// Calling this function is safe, but using the raw hash table API may
1346    /// require unsafe functions or blocks.
1347    ///
1348    /// `RawTable` API gives the lowest level of control under the set that can
1349    /// be useful for extending the HashSet's API, but may lead to *[undefined
1350    /// behavior]*.
1351    ///
1352    /// [`RawTable`]: crate::hashbrown::raw::RawTable
1353    /// [undefined behavior]:
1354    ///     https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1355    #[cfg_attr(feature = "inline-more", inline)]
1356    pub fn raw_table_mut(&mut self) -> &mut RawTable<(T, ()), A> {
1357        self.map.raw_table_mut()
1358    }
1359}
1360
1361impl<T, S, A> PartialEq for HashSet<T, S, A>
1362where
1363    T: Eq + Hash,
1364    S: BuildHasher,
1365    A: Allocator,
1366{
1367    fn eq(&self, other: &Self) -> bool {
1368        if self.len() != other.len() {
1369            return false;
1370        }
1371
1372        self.iter().all(|key| other.contains(key))
1373    }
1374}
1375
1376impl<T, S, A> Eq for HashSet<T, S, A>
1377where
1378    T: Eq + Hash,
1379    S: BuildHasher,
1380    A: Allocator,
1381{
1382}
1383
1384impl<T, S, A> fmt::Debug for HashSet<T, S, A>
1385where
1386    T: fmt::Debug,
1387    A: Allocator,
1388{
1389    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1390        f.debug_set().entries(self.iter()).finish()
1391    }
1392}
1393
1394impl<T, S, A> From<HashMap<T, (), S, A>> for HashSet<T, S, A>
1395where
1396    A: Allocator,
1397{
1398    fn from(map: HashMap<T, (), S, A>) -> Self {
1399        Self { map }
1400    }
1401}
1402
1403impl<T, S, A: Allocator> TryFromIteratorIn<T, A> for HashSet<T, S, A>
1404where
1405    T: Eq + Hash,
1406    S: BuildHasher + Default,
1407{
1408    #[cfg_attr(feature = "inline-more", inline)]
1409    fn try_from_iter_in<I: IntoIterator<Item = T>>(iter: I, alloc: A) -> Result<Self, Error> {
1410        let mut set = Self::with_hasher_in(S::default(), alloc);
1411        set.try_extend(iter)?;
1412        Ok(set)
1413    }
1414}
1415
1416#[cfg(test)]
1417impl<T, S, A: Allocator + Default> FromIterator<T> for HashSet<T, S, A>
1418where
1419    T: Eq + Hash,
1420    S: BuildHasher + Default,
1421{
1422    #[inline]
1423    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
1424        Self::try_from_iter_in(iter, A::default()).abort()
1425    }
1426}
1427
1428// The default hasher is used to match the std implementation signature
1429impl<T, A: Allocator + Default, const N: usize> TryFrom<[T; N]>
1430    for HashSet<T, DefaultHashBuilder, A>
1431where
1432    T: Eq + Hash,
1433{
1434    type Error = Error;
1435
1436    /// # Examples
1437    ///
1438    /// ```
1439    /// use rune::alloc::HashSet;
1440    ///
1441    /// let set1: HashSet<_> = HashSet::try_from([1, 2, 3, 4])?;
1442    /// let set2: HashSet<_> = [1, 2, 3, 4].try_into()?;
1443    /// assert_eq!(set1, set2);
1444    /// # Ok::<_, rune::alloc::Error>(())
1445    /// ```
1446    fn try_from(arr: [T; N]) -> Result<Self, Self::Error> {
1447        Self::try_from_iter_in(arr, A::default())
1448    }
1449}
1450
1451impl<T, S, A> TryExtend<T> for HashSet<T, S, A>
1452where
1453    T: Eq + Hash,
1454    S: BuildHasher,
1455    A: Allocator,
1456{
1457    #[cfg_attr(feature = "inline-more", inline)]
1458    fn try_extend<I: IntoIterator<Item = T>>(&mut self, iter: I) -> Result<(), Error> {
1459        self.map.try_extend(iter.into_iter().map(|k| (k, ())))
1460    }
1461}
1462
1463#[cfg(test)]
1464impl<T, S, A> Extend<T> for HashSet<T, S, A>
1465where
1466    T: Eq + Hash,
1467    S: BuildHasher,
1468    A: Allocator,
1469{
1470    #[cfg_attr(feature = "inline-more", inline)]
1471    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
1472        self.try_extend(iter).abort();
1473    }
1474}
1475
1476impl<'a, T, S, A> TryExtend<&'a T> for HashSet<T, S, A>
1477where
1478    T: 'a + Eq + Hash + Copy,
1479    S: BuildHasher,
1480    A: Allocator,
1481{
1482    #[cfg_attr(feature = "inline-more", inline)]
1483    fn try_extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) -> Result<(), Error> {
1484        self.try_extend(iter.into_iter().copied())
1485    }
1486}
1487
1488#[cfg(test)]
1489impl<'a, T, S, A> Extend<&'a T> for HashSet<T, S, A>
1490where
1491    T: 'a + Eq + Hash + Copy,
1492    S: BuildHasher,
1493    A: Allocator,
1494{
1495    #[cfg_attr(feature = "inline-more", inline)]
1496    fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
1497        self.try_extend(iter).abort()
1498    }
1499}
1500
1501impl<T, S, A> Default for HashSet<T, S, A>
1502where
1503    S: Default,
1504    A: Default + Allocator,
1505{
1506    /// Creates an empty `HashSet<T, S>` with the `Default` value for the hasher.
1507    #[cfg_attr(feature = "inline-more", inline)]
1508    fn default() -> Self {
1509        Self {
1510            map: HashMap::default(),
1511        }
1512    }
1513}
1514
1515/// An iterator over the items of a `HashSet`.
1516///
1517/// This `struct` is created by the [`iter`] method on [`HashSet`].
1518/// See its documentation for more.
1519///
1520/// [`HashSet`]: struct.HashSet.html
1521/// [`iter`]: struct.HashSet.html#method.iter
1522pub struct Iter<'a, K> {
1523    iter: Keys<'a, K, ()>,
1524}
1525
1526/// An owning iterator over the items of a `HashSet`.
1527///
1528/// This `struct` is created by the [`into_iter`] method on [`HashSet`]
1529/// (provided by the `IntoIterator` trait). See its documentation for more.
1530///
1531/// [`HashSet`]: struct.HashSet.html
1532/// [`into_iter`]: struct.HashSet.html#method.into_iter
1533pub struct IntoIter<K, A: Allocator = Global> {
1534    iter: map::IntoIter<K, (), A>,
1535}
1536
1537/// A draining iterator over the items of a `HashSet`.
1538///
1539/// This `struct` is created by the [`drain`] method on [`HashSet`].
1540/// See its documentation for more.
1541///
1542/// [`HashSet`]: struct.HashSet.html
1543/// [`drain`]: struct.HashSet.html#method.drain
1544pub struct Drain<'a, K, A: Allocator = Global> {
1545    iter: map::Drain<'a, K, (), A>,
1546}
1547
1548/// A draining iterator over entries of a `HashSet` which don't satisfy the predicate `f`.
1549///
1550/// This `struct` is created by the [`extract_if`] method on [`HashSet`]. See its
1551/// documentation for more.
1552///
1553/// [`extract_if`]: struct.HashSet.html#method.extract_if
1554/// [`HashSet`]: struct.HashSet.html
1555#[must_use = "Iterators are lazy unless consumed"]
1556pub struct ExtractIf<'a, K, F, A: Allocator = Global>
1557where
1558    F: FnMut(&K) -> bool,
1559{
1560    f: F,
1561    inner: ExtractIfInner<'a, K, (), A>,
1562}
1563
1564/// A lazy iterator producing elements in the intersection of `HashSet`s.
1565///
1566/// This `struct` is created by the [`intersection`] method on [`HashSet`].
1567/// See its documentation for more.
1568///
1569/// [`HashSet`]: struct.HashSet.html
1570/// [`intersection`]: struct.HashSet.html#method.intersection
1571pub struct Intersection<'a, T, S, A: Allocator = Global> {
1572    // iterator of the first set
1573    iter: Iter<'a, T>,
1574    // the second set
1575    other: &'a HashSet<T, S, A>,
1576}
1577
1578/// A lazy iterator producing elements in the difference of `HashSet`s.
1579///
1580/// This `struct` is created by the [`difference`] method on [`HashSet`].
1581/// See its documentation for more.
1582///
1583/// [`HashSet`]: struct.HashSet.html
1584/// [`difference`]: struct.HashSet.html#method.difference
1585pub struct Difference<'a, T, S, A: Allocator = Global> {
1586    // iterator of the first set
1587    iter: Iter<'a, T>,
1588    // the second set
1589    other: &'a HashSet<T, S, A>,
1590}
1591
1592/// A lazy iterator producing elements in the symmetric difference of `HashSet`s.
1593///
1594/// This `struct` is created by the [`symmetric_difference`] method on
1595/// [`HashSet`]. See its documentation for more.
1596///
1597/// [`HashSet`]: struct.HashSet.html
1598/// [`symmetric_difference`]: struct.HashSet.html#method.symmetric_difference
1599pub struct SymmetricDifference<'a, T, S, A: Allocator = Global> {
1600    iter: Chain<Difference<'a, T, S, A>, Difference<'a, T, S, A>>,
1601}
1602
1603/// A lazy iterator producing elements in the union of `HashSet`s.
1604///
1605/// This `struct` is created by the [`union`] method on [`HashSet`].
1606/// See its documentation for more.
1607///
1608/// [`HashSet`]: struct.HashSet.html
1609/// [`union`]: struct.HashSet.html#method.union
1610pub struct Union<'a, T, S, A: Allocator = Global> {
1611    iter: Chain<Iter<'a, T>, Difference<'a, T, S, A>>,
1612}
1613
1614impl<'a, T, S, A: Allocator> IntoIterator for &'a HashSet<T, S, A> {
1615    type Item = &'a T;
1616    type IntoIter = Iter<'a, T>;
1617
1618    #[cfg_attr(feature = "inline-more", inline)]
1619    fn into_iter(self) -> Iter<'a, T> {
1620        self.iter()
1621    }
1622}
1623
1624impl<T, S, A: Allocator> IntoIterator for HashSet<T, S, A> {
1625    type Item = T;
1626    type IntoIter = IntoIter<T, A>;
1627
1628    /// Creates a consuming iterator, that is, one that moves each value out
1629    /// of the set in arbitrary order. The set cannot be used after calling
1630    /// this.
1631    ///
1632    /// # Examples
1633    ///
1634    /// ```
1635    /// use rune::alloc::{HashSet, Vec};
1636    /// use rune::alloc::prelude::*;
1637    ///
1638    /// let mut set = HashSet::new();
1639    /// set.try_insert("a".to_string())?;
1640    /// set.try_insert("b".to_string())?;
1641    ///
1642    /// // Not possible to collect to a Vec<String> with a regular `.iter()`.
1643    /// let v: Vec<String> = set.into_iter().try_collect()?;
1644    ///
1645    /// // Will print in an arbitrary order.
1646    /// for x in &v {
1647    ///     println!("{}", x);
1648    /// }
1649    /// # Ok::<_, rune::alloc::Error>(())
1650    /// ```
1651    #[cfg_attr(feature = "inline-more", inline)]
1652    fn into_iter(self) -> IntoIter<T, A> {
1653        IntoIter {
1654            iter: self.map.into_iter(),
1655        }
1656    }
1657}
1658
1659impl<K> Clone for Iter<'_, K> {
1660    #[cfg_attr(feature = "inline-more", inline)]
1661    fn clone(&self) -> Self {
1662        Iter {
1663            iter: self.iter.clone(),
1664        }
1665    }
1666}
1667impl<'a, K> Iterator for Iter<'a, K> {
1668    type Item = &'a K;
1669
1670    #[cfg_attr(feature = "inline-more", inline)]
1671    fn next(&mut self) -> Option<&'a K> {
1672        self.iter.next()
1673    }
1674    #[cfg_attr(feature = "inline-more", inline)]
1675    fn size_hint(&self) -> (usize, Option<usize>) {
1676        self.iter.size_hint()
1677    }
1678}
1679impl<'a, K> ExactSizeIterator for Iter<'a, K> {
1680    #[cfg_attr(feature = "inline-more", inline)]
1681    fn len(&self) -> usize {
1682        self.iter.len()
1683    }
1684}
1685impl<K> FusedIterator for Iter<'_, K> {}
1686
1687impl<K: fmt::Debug> fmt::Debug for Iter<'_, K> {
1688    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1689        f.debug_list().entries(self.clone()).finish()
1690    }
1691}
1692
1693impl<K, A: Allocator> Iterator for IntoIter<K, A> {
1694    type Item = K;
1695
1696    #[cfg_attr(feature = "inline-more", inline)]
1697    fn next(&mut self) -> Option<K> {
1698        // Avoid `Option::map` because it bloats LLVM IR.
1699        match self.iter.next() {
1700            Some((k, _)) => Some(k),
1701            None => None,
1702        }
1703    }
1704    #[cfg_attr(feature = "inline-more", inline)]
1705    fn size_hint(&self) -> (usize, Option<usize>) {
1706        self.iter.size_hint()
1707    }
1708}
1709impl<K, A: Allocator> ExactSizeIterator for IntoIter<K, A> {
1710    #[cfg_attr(feature = "inline-more", inline)]
1711    fn len(&self) -> usize {
1712        self.iter.len()
1713    }
1714}
1715impl<K, A: Allocator> FusedIterator for IntoIter<K, A> {}
1716
1717impl<K: fmt::Debug, A: Allocator> fmt::Debug for IntoIter<K, A> {
1718    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1719        let entries_iter = self.iter.iter().map(|(k, _)| k);
1720        f.debug_list().entries(entries_iter).finish()
1721    }
1722}
1723
1724impl<K, A: Allocator> Iterator for Drain<'_, K, A> {
1725    type Item = K;
1726
1727    #[cfg_attr(feature = "inline-more", inline)]
1728    fn next(&mut self) -> Option<K> {
1729        // Avoid `Option::map` because it bloats LLVM IR.
1730        match self.iter.next() {
1731            Some((k, _)) => Some(k),
1732            None => None,
1733        }
1734    }
1735    #[cfg_attr(feature = "inline-more", inline)]
1736    fn size_hint(&self) -> (usize, Option<usize>) {
1737        self.iter.size_hint()
1738    }
1739}
1740impl<K, A: Allocator> ExactSizeIterator for Drain<'_, K, A> {
1741    #[cfg_attr(feature = "inline-more", inline)]
1742    fn len(&self) -> usize {
1743        self.iter.len()
1744    }
1745}
1746impl<K, A: Allocator> FusedIterator for Drain<'_, K, A> {}
1747
1748impl<K: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, K, A> {
1749    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1750        let entries_iter = self.iter.iter().map(|(k, _)| k);
1751        f.debug_list().entries(entries_iter).finish()
1752    }
1753}
1754
1755impl<K, F, A: Allocator> Iterator for ExtractIf<'_, K, F, A>
1756where
1757    F: FnMut(&K) -> bool,
1758{
1759    type Item = K;
1760
1761    #[cfg_attr(feature = "inline-more", inline)]
1762    fn next(&mut self) -> Option<Self::Item> {
1763        let f = &mut self.f;
1764        let (k, _) = self.inner.next(&mut |k, _| f(k))?;
1765        Some(k)
1766    }
1767
1768    #[inline]
1769    fn size_hint(&self) -> (usize, Option<usize>) {
1770        (0, self.inner.iter.size_hint().1)
1771    }
1772}
1773
1774impl<K, F, A: Allocator> FusedIterator for ExtractIf<'_, K, F, A> where F: FnMut(&K) -> bool {}
1775
1776impl<T, S, A: Allocator> Clone for Intersection<'_, T, S, A> {
1777    #[cfg_attr(feature = "inline-more", inline)]
1778    fn clone(&self) -> Self {
1779        Intersection {
1780            iter: self.iter.clone(),
1781            ..*self
1782        }
1783    }
1784}
1785
1786impl<'a, T, S, A> Iterator for Intersection<'a, T, S, A>
1787where
1788    T: Eq + Hash,
1789    S: BuildHasher,
1790    A: Allocator,
1791{
1792    type Item = &'a T;
1793
1794    #[cfg_attr(feature = "inline-more", inline)]
1795    fn next(&mut self) -> Option<&'a T> {
1796        loop {
1797            let elt = self.iter.next()?;
1798            if self.other.contains(elt) {
1799                return Some(elt);
1800            }
1801        }
1802    }
1803
1804    #[cfg_attr(feature = "inline-more", inline)]
1805    fn size_hint(&self) -> (usize, Option<usize>) {
1806        let (_, upper) = self.iter.size_hint();
1807        (0, upper)
1808    }
1809}
1810
1811impl<T, S, A> fmt::Debug for Intersection<'_, T, S, A>
1812where
1813    T: fmt::Debug + Eq + Hash,
1814    S: BuildHasher,
1815    A: Allocator,
1816{
1817    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1818        f.debug_list().entries(self.clone()).finish()
1819    }
1820}
1821
1822impl<T, S, A> FusedIterator for Intersection<'_, T, S, A>
1823where
1824    T: Eq + Hash,
1825    S: BuildHasher,
1826    A: Allocator,
1827{
1828}
1829
1830impl<T, S, A: Allocator> Clone for Difference<'_, T, S, A> {
1831    #[cfg_attr(feature = "inline-more", inline)]
1832    fn clone(&self) -> Self {
1833        Difference {
1834            iter: self.iter.clone(),
1835            ..*self
1836        }
1837    }
1838}
1839
1840impl<'a, T, S, A> Iterator for Difference<'a, T, S, A>
1841where
1842    T: Eq + Hash,
1843    S: BuildHasher,
1844    A: Allocator,
1845{
1846    type Item = &'a T;
1847
1848    #[cfg_attr(feature = "inline-more", inline)]
1849    fn next(&mut self) -> Option<&'a T> {
1850        loop {
1851            let elt = self.iter.next()?;
1852            if !self.other.contains(elt) {
1853                return Some(elt);
1854            }
1855        }
1856    }
1857
1858    #[cfg_attr(feature = "inline-more", inline)]
1859    fn size_hint(&self) -> (usize, Option<usize>) {
1860        let (_, upper) = self.iter.size_hint();
1861        (0, upper)
1862    }
1863}
1864
1865impl<T, S, A> FusedIterator for Difference<'_, T, S, A>
1866where
1867    T: Eq + Hash,
1868    S: BuildHasher,
1869    A: Allocator,
1870{
1871}
1872
1873impl<T, S, A> fmt::Debug for Difference<'_, T, S, A>
1874where
1875    T: fmt::Debug + Eq + Hash,
1876    S: BuildHasher,
1877    A: Allocator,
1878{
1879    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1880        f.debug_list().entries(self.clone()).finish()
1881    }
1882}
1883
1884impl<T, S, A: Allocator> Clone for SymmetricDifference<'_, T, S, A> {
1885    #[cfg_attr(feature = "inline-more", inline)]
1886    fn clone(&self) -> Self {
1887        SymmetricDifference {
1888            iter: self.iter.clone(),
1889        }
1890    }
1891}
1892
1893impl<'a, T, S, A> Iterator for SymmetricDifference<'a, T, S, A>
1894where
1895    T: Eq + Hash,
1896    S: BuildHasher,
1897    A: Allocator,
1898{
1899    type Item = &'a T;
1900
1901    #[cfg_attr(feature = "inline-more", inline)]
1902    fn next(&mut self) -> Option<&'a T> {
1903        self.iter.next()
1904    }
1905    #[cfg_attr(feature = "inline-more", inline)]
1906    fn size_hint(&self) -> (usize, Option<usize>) {
1907        self.iter.size_hint()
1908    }
1909}
1910
1911impl<T, S, A> FusedIterator for SymmetricDifference<'_, T, S, A>
1912where
1913    T: Eq + Hash,
1914    S: BuildHasher,
1915    A: Allocator,
1916{
1917}
1918
1919impl<T, S, A> fmt::Debug for SymmetricDifference<'_, T, S, A>
1920where
1921    T: fmt::Debug + Eq + Hash,
1922    S: BuildHasher,
1923    A: Allocator,
1924{
1925    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1926        f.debug_list().entries(self.clone()).finish()
1927    }
1928}
1929
1930impl<T, S, A: Allocator> Clone for Union<'_, T, S, A> {
1931    #[cfg_attr(feature = "inline-more", inline)]
1932    fn clone(&self) -> Self {
1933        Union {
1934            iter: self.iter.clone(),
1935        }
1936    }
1937}
1938
1939impl<T, S, A> FusedIterator for Union<'_, T, S, A>
1940where
1941    T: Eq + Hash,
1942    S: BuildHasher,
1943    A: Allocator,
1944{
1945}
1946
1947impl<T, S, A> fmt::Debug for Union<'_, T, S, A>
1948where
1949    T: fmt::Debug + Eq + Hash,
1950    S: BuildHasher,
1951    A: Allocator,
1952{
1953    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1954        f.debug_list().entries(self.clone()).finish()
1955    }
1956}
1957
1958impl<'a, T, S, A> Iterator for Union<'a, T, S, A>
1959where
1960    T: Eq + Hash,
1961    S: BuildHasher,
1962    A: Allocator,
1963{
1964    type Item = &'a T;
1965
1966    #[cfg_attr(feature = "inline-more", inline)]
1967    fn next(&mut self) -> Option<&'a T> {
1968        self.iter.next()
1969    }
1970    #[cfg_attr(feature = "inline-more", inline)]
1971    fn size_hint(&self) -> (usize, Option<usize>) {
1972        self.iter.size_hint()
1973    }
1974}
1975
1976/// A view into a single entry in a set, which may either be vacant or occupied.
1977///
1978/// This `enum` is constructed from the [`entry`] method on [`HashSet`].
1979///
1980/// [`HashSet`]: struct.HashSet.html
1981/// [`entry`]: struct.HashSet.html#method.entry
1982///
1983/// # Examples
1984///
1985/// ```
1986/// use rune::alloc::{HashSet, Vec};
1987/// use rune::alloc::hash_set::{Entry, OccupiedEntry};
1988/// use rune::alloc::prelude::*;
1989///
1990/// let mut set = HashSet::new();
1991/// set.try_extend(["a", "b", "c"])?;
1992/// assert_eq!(set.len(), 3);
1993///
1994/// // Existing value (insert)
1995/// let entry: Entry<_, _> = set.entry("a");
1996/// let _raw_o: OccupiedEntry<_, _> = entry.try_insert()?;
1997/// assert_eq!(set.len(), 3);
1998/// // Nonexistent value (insert)
1999/// set.entry("d").try_insert()?;
2000///
2001/// // Existing value (or_try_insert)
2002/// set.entry("b").or_try_insert()?;
2003/// // Nonexistent value (or_try_insert)
2004/// set.entry("e").or_try_insert()?;
2005///
2006/// println!("Our HashSet: {:?}", set);
2007///
2008/// let mut vec: Vec<_> = set.iter().copied().try_collect()?;
2009/// // The `Iter` iterator produces items in arbitrary order, so the
2010/// // items must be sorted to test them against a sorted array.
2011/// vec.sort_unstable();
2012/// assert_eq!(vec, ["a", "b", "c", "d", "e"]);
2013/// # Ok::<_, rune::alloc::Error>(())
2014/// ```
2015pub enum Entry<'a, T, S, A = Global>
2016where
2017    A: Allocator,
2018{
2019    /// An occupied entry.
2020    ///
2021    /// # Examples
2022    ///
2023    /// ```
2024    /// use rune::alloc::hash_set::Entry;
2025    /// use rune::alloc::HashSet;
2026    ///
2027    /// let mut set: HashSet<_> = HashSet::try_from(["a", "b"])?;
2028    ///
2029    /// match set.entry("a") {
2030    ///     Entry::Vacant(_) => unreachable!(),
2031    ///     Entry::Occupied(_) => { }
2032    /// }
2033    /// # Ok::<_, rune::alloc::Error>(())
2034    /// ```
2035    Occupied(OccupiedEntry<'a, T, S, A>),
2036
2037    /// A vacant entry.
2038    ///
2039    /// # Examples
2040    ///
2041    /// ```
2042    /// use rune::alloc::hash_set::{Entry, HashSet};
2043    /// let mut set = HashSet::new();
2044    ///
2045    /// match set.entry("a") {
2046    ///     Entry::Occupied(_) => unreachable!(),
2047    ///     Entry::Vacant(_) => { }
2048    /// }
2049    /// # Ok::<_, rune::alloc::Error>(())
2050    /// ```
2051    Vacant(VacantEntry<'a, T, S, A>),
2052}
2053
2054impl<T: fmt::Debug, S, A: Allocator> fmt::Debug for Entry<'_, T, S, A> {
2055    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2056        match *self {
2057            Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
2058            Entry::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
2059        }
2060    }
2061}
2062
2063/// A view into an occupied entry in a `HashSet`.
2064/// It is part of the [`Entry`] enum.
2065///
2066/// [`Entry`]: enum.Entry.html
2067///
2068/// # Examples
2069///
2070/// ```
2071/// use rune::alloc::hash_set::{Entry, HashSet, OccupiedEntry};
2072/// use rune::alloc::prelude::*;
2073///
2074/// let mut set = HashSet::new();
2075/// set.try_extend(["a", "b", "c"])?;
2076///
2077/// let _entry_o: OccupiedEntry<_, _> = set.entry("a").try_insert()?;
2078/// assert_eq!(set.len(), 3);
2079///
2080/// // Existing key
2081/// match set.entry("a") {
2082///     Entry::Vacant(_) => unreachable!(),
2083///     Entry::Occupied(view) => {
2084///         assert_eq!(view.get(), &"a");
2085///     }
2086/// }
2087///
2088/// assert_eq!(set.len(), 3);
2089///
2090/// // Existing key (take)
2091/// match set.entry("c") {
2092///     Entry::Vacant(_) => unreachable!(),
2093///     Entry::Occupied(view) => {
2094///         assert_eq!(view.remove(), "c");
2095///     }
2096/// }
2097/// assert_eq!(set.get(&"c"), None);
2098/// assert_eq!(set.len(), 2);
2099/// # Ok::<_, rune::alloc::Error>(())
2100/// ```
2101pub struct OccupiedEntry<'a, T, S, A: Allocator = Global> {
2102    inner: map::OccupiedEntry<'a, T, (), S, A>,
2103}
2104
2105impl<T: fmt::Debug, S, A: Allocator> fmt::Debug for OccupiedEntry<'_, T, S, A> {
2106    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2107        f.debug_struct("OccupiedEntry")
2108            .field("value", self.get())
2109            .finish()
2110    }
2111}
2112
2113/// A view into a vacant entry in a `HashSet`.
2114/// It is part of the [`Entry`] enum.
2115///
2116/// [`Entry`]: enum.Entry.html
2117///
2118/// # Examples
2119///
2120/// ```
2121/// use rune::alloc::hash_set::{Entry, HashSet, VacantEntry};
2122///
2123/// let mut set = HashSet::<&str>::new();
2124///
2125/// let entry_v: VacantEntry<_, _> = match set.entry("a") {
2126///     Entry::Vacant(view) => view,
2127///     Entry::Occupied(_) => unreachable!(),
2128/// };
2129/// entry_v.try_insert()?;
2130/// assert!(set.contains("a") && set.len() == 1);
2131///
2132/// // Nonexistent key (try_insert)
2133/// match set.entry("b") {
2134///     Entry::Vacant(view) => view.try_insert()?,
2135///     Entry::Occupied(_) => unreachable!(),
2136/// }
2137/// assert!(set.contains("b") && set.len() == 2);
2138/// # Ok::<_, rune::alloc::Error>(())
2139/// ```
2140pub struct VacantEntry<'a, T, S, A: Allocator = Global> {
2141    inner: map::VacantEntry<'a, T, (), S, A>,
2142}
2143
2144impl<T: fmt::Debug, S, A: Allocator> fmt::Debug for VacantEntry<'_, T, S, A> {
2145    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2146        f.debug_tuple("VacantEntry").field(self.get()).finish()
2147    }
2148}
2149
2150impl<'a, T, S, A: Allocator> Entry<'a, T, S, A> {
2151    /// Sets the value of the entry, and returns an OccupiedEntry.
2152    ///
2153    /// # Examples
2154    ///
2155    /// ```
2156    /// use rune::alloc::HashSet;
2157    ///
2158    /// let mut set: HashSet<&str> = HashSet::new();
2159    /// let entry = set.entry("horseyland").try_insert()?;
2160    ///
2161    /// assert_eq!(entry.get(), &"horseyland");
2162    /// # Ok::<_, rune::alloc::Error>(())
2163    /// ```
2164    #[cfg_attr(feature = "inline-more", inline)]
2165    pub fn try_insert(self) -> Result<OccupiedEntry<'a, T, S, A>, Error>
2166    where
2167        T: Hash,
2168        S: BuildHasher,
2169    {
2170        match self {
2171            Entry::Occupied(entry) => Ok(entry),
2172            Entry::Vacant(entry) => entry.try_insert_entry(),
2173        }
2174    }
2175
2176    /// Ensures a value is in the entry by inserting if it was vacant.
2177    ///
2178    /// # Examples
2179    ///
2180    /// ```
2181    /// use rune::alloc::HashSet;
2182    ///
2183    /// let mut set: HashSet<&str> = HashSet::new();
2184    ///
2185    /// // nonexistent key
2186    /// set.entry("poneyland").or_try_insert()?;
2187    /// assert!(set.contains("poneyland"));
2188    ///
2189    /// // existing key
2190    /// set.entry("poneyland").or_try_insert()?;
2191    /// assert!(set.contains("poneyland"));
2192    /// assert_eq!(set.len(), 1);
2193    /// # Ok::<_, rune::alloc::Error>(())
2194    /// ```
2195    #[cfg_attr(feature = "inline-more", inline)]
2196    pub fn or_try_insert(self) -> Result<(), Error>
2197    where
2198        T: Hash,
2199        S: BuildHasher,
2200    {
2201        if let Entry::Vacant(entry) = self {
2202            entry.try_insert()?;
2203        }
2204
2205        Ok(())
2206    }
2207
2208    /// Returns a reference to this entry's value.
2209    ///
2210    /// # Examples
2211    ///
2212    /// ```
2213    /// use rune::alloc::HashSet;
2214    ///
2215    /// let mut set: HashSet<&str> = HashSet::new();
2216    /// set.entry("poneyland").or_try_insert()?;
2217    /// // existing key
2218    /// assert_eq!(set.entry("poneyland").get(), &"poneyland");
2219    /// // nonexistent key
2220    /// assert_eq!(set.entry("horseland").get(), &"horseland");
2221    /// # Ok::<_, rune::alloc::Error>(())
2222    /// ```
2223    #[cfg_attr(feature = "inline-more", inline)]
2224    pub fn get(&self) -> &T {
2225        match *self {
2226            Entry::Occupied(ref entry) => entry.get(),
2227            Entry::Vacant(ref entry) => entry.get(),
2228        }
2229    }
2230}
2231
2232impl<T, S, A: Allocator> OccupiedEntry<'_, T, S, A> {
2233    /// Gets a reference to the value in the entry.
2234    ///
2235    /// # Examples
2236    ///
2237    /// ```
2238    /// use rune::alloc::hash_set::{Entry, HashSet};
2239    ///
2240    /// let mut set: HashSet<&str> = HashSet::new();
2241    /// set.entry("poneyland").or_try_insert()?;
2242    ///
2243    /// match set.entry("poneyland") {
2244    ///     Entry::Vacant(_) => panic!(),
2245    ///     Entry::Occupied(entry) => assert_eq!(entry.get(), &"poneyland"),
2246    /// }
2247    /// # Ok::<_, rune::alloc::Error>(())
2248    /// ```
2249    #[cfg_attr(feature = "inline-more", inline)]
2250    pub fn get(&self) -> &T {
2251        self.inner.key()
2252    }
2253
2254    /// Takes the value out of the entry, and returns it.
2255    /// Keeps the allocated memory for reuse.
2256    ///
2257    /// # Examples
2258    ///
2259    /// ```
2260    /// use rune::alloc::HashSet;
2261    /// use rune::alloc::hash_set::Entry;
2262    ///
2263    /// let mut set: HashSet<&str> = HashSet::new();
2264    /// // The set is empty
2265    /// assert!(set.is_empty() && set.capacity() == 0);
2266    ///
2267    /// set.entry("poneyland").or_try_insert()?;
2268    /// let capacity_before_remove = set.capacity();
2269    ///
2270    /// if let Entry::Occupied(o) = set.entry("poneyland") {
2271    ///     assert_eq!(o.remove(), "poneyland");
2272    /// }
2273    ///
2274    /// assert_eq!(set.contains("poneyland"), false);
2275    /// // Now set hold none elements but capacity is equal to the old one
2276    /// assert!(set.len() == 0 && set.capacity() == capacity_before_remove);
2277    /// # Ok::<_, rune::alloc::Error>(())
2278    /// ```
2279    #[cfg_attr(feature = "inline-more", inline)]
2280    pub fn remove(self) -> T {
2281        self.inner.remove_entry().0
2282    }
2283
2284    /// Replaces the entry, returning the old value. The new value in the hash
2285    /// map will be the value used to create this entry.
2286    ///
2287    /// # Panics
2288    ///
2289    /// Will panic if this OccupiedEntry was created through
2290    /// [`Entry::try_insert`].
2291    ///
2292    /// # Examples
2293    ///
2294    /// ```
2295    /// use rune::alloc::hash_set::{Entry, HashSet};
2296    /// use std::rc::Rc;
2297    ///
2298    /// let mut set: HashSet<Rc<String>> = HashSet::new();
2299    /// let key_one = Rc::new("Stringthing".to_string());
2300    /// let key_two = Rc::new("Stringthing".to_string());
2301    ///
2302    /// set.try_insert(key_one.clone())?;
2303    /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
2304    ///
2305    /// match set.entry(key_two.clone()) {
2306    ///     Entry::Occupied(entry) => {
2307    ///         let old_key: Rc<String> = entry.replace();
2308    ///         assert!(Rc::ptr_eq(&key_one, &old_key));
2309    ///     }
2310    ///     Entry::Vacant(_) => panic!(),
2311    /// }
2312    ///
2313    /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
2314    /// assert!(set.contains(&"Stringthing".to_owned()));
2315    /// # Ok::<_, rune::alloc::Error>(())
2316    /// ```
2317    #[cfg_attr(feature = "inline-more", inline)]
2318    pub fn replace(self) -> T {
2319        self.inner.replace_key()
2320    }
2321}
2322
2323impl<'a, T, S, A: Allocator> VacantEntry<'a, T, S, A> {
2324    /// Gets a reference to the value that would be used when inserting
2325    /// through the `VacantEntry`.
2326    ///
2327    /// # Examples
2328    ///
2329    /// ```
2330    /// use rune::alloc::HashSet;
2331    ///
2332    /// let mut set: HashSet<&str> = HashSet::new();
2333    /// assert_eq!(set.entry("poneyland").get(), &"poneyland");
2334    /// ```
2335    #[cfg_attr(feature = "inline-more", inline)]
2336    pub fn get(&self) -> &T {
2337        self.inner.key()
2338    }
2339
2340    /// Take ownership of the value.
2341    ///
2342    /// # Examples
2343    ///
2344    /// ```
2345    /// use rune::alloc::hash_set::{Entry, HashSet};
2346    ///
2347    /// let mut set = HashSet::new();
2348    ///
2349    /// match set.entry("poneyland") {
2350    ///     Entry::Occupied(_) => panic!(),
2351    ///     Entry::Vacant(v) => assert_eq!(v.into_value(), "poneyland"),
2352    /// }
2353    /// ```
2354    #[cfg_attr(feature = "inline-more", inline)]
2355    pub fn into_value(self) -> T {
2356        self.inner.into_key()
2357    }
2358
2359    /// Sets the value of the entry with the VacantEntry's value.
2360    ///
2361    /// # Examples
2362    ///
2363    /// ```
2364    /// use rune::alloc::HashSet;
2365    /// use rune::alloc::hash_set::Entry;
2366    ///
2367    /// let mut set: HashSet<&str> = HashSet::new();
2368    ///
2369    /// if let Entry::Vacant(o) = set.entry("poneyland") {
2370    ///     o.try_insert()?;
2371    /// }
2372    /// assert!(set.contains("poneyland"));
2373    /// # Ok::<_, rune::alloc::Error>(())
2374    /// ```
2375    #[cfg_attr(feature = "inline-more", inline)]
2376    pub fn try_insert(self) -> Result<(), Error>
2377    where
2378        T: Hash,
2379        S: BuildHasher,
2380    {
2381        self.inner.try_insert(())?;
2382        Ok(())
2383    }
2384
2385    #[cfg_attr(feature = "inline-more", inline)]
2386    fn try_insert_entry(self) -> Result<OccupiedEntry<'a, T, S, A>, Error>
2387    where
2388        T: Hash,
2389        S: BuildHasher,
2390    {
2391        Ok(OccupiedEntry {
2392            inner: self.inner.try_insert_entry(())?,
2393        })
2394    }
2395}
2396
2397#[allow(dead_code)]
2398fn assert_covariance() {
2399    fn set<'new>(v: HashSet<&'static str>) -> HashSet<&'new str> {
2400        v
2401    }
2402    fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> {
2403        v
2404    }
2405    fn into_iter<'new, A: Allocator>(v: IntoIter<&'static str, A>) -> IntoIter<&'new str, A> {
2406        v
2407    }
2408    fn difference<'a, 'new, A: Allocator>(
2409        v: Difference<'a, &'static str, DefaultHashBuilder, A>,
2410    ) -> Difference<'a, &'new str, DefaultHashBuilder, A> {
2411        v
2412    }
2413    fn symmetric_difference<'a, 'new, A: Allocator>(
2414        v: SymmetricDifference<'a, &'static str, DefaultHashBuilder, A>,
2415    ) -> SymmetricDifference<'a, &'new str, DefaultHashBuilder, A> {
2416        v
2417    }
2418    fn intersection<'a, 'new, A: Allocator>(
2419        v: Intersection<'a, &'static str, DefaultHashBuilder, A>,
2420    ) -> Intersection<'a, &'new str, DefaultHashBuilder, A> {
2421        v
2422    }
2423    fn union<'a, 'new, A: Allocator>(
2424        v: Union<'a, &'static str, DefaultHashBuilder, A>,
2425    ) -> Union<'a, &'new str, DefaultHashBuilder, A> {
2426        v
2427    }
2428    fn drain<'new, A: Allocator>(d: Drain<'static, &'static str, A>) -> Drain<'new, &'new str, A> {
2429        d
2430    }
2431}
2432
2433#[cfg(test)]
2434mod test_set {
2435    use super::super::map::DefaultHashBuilder;
2436    use super::HashSet;
2437    use rust_alloc::vec::Vec;
2438    use rust_alloc::{format, vec};
2439
2440    #[test]
2441    fn test_zero_capacities() {
2442        type HS = HashSet<i32>;
2443
2444        let s = HS::new();
2445        assert_eq!(s.capacity(), 0);
2446
2447        let s = HS::default();
2448        assert_eq!(s.capacity(), 0);
2449
2450        let s = HS::with_hasher(DefaultHashBuilder::default());
2451        assert_eq!(s.capacity(), 0);
2452
2453        let s = HS::with_capacity(0);
2454        assert_eq!(s.capacity(), 0);
2455
2456        let s = HS::with_capacity_and_hasher(0, DefaultHashBuilder::default());
2457        assert_eq!(s.capacity(), 0);
2458
2459        let mut s = HS::new();
2460        s.insert(1);
2461        s.insert(2);
2462        s.remove(&1);
2463        s.remove(&2);
2464        s.shrink_to_fit();
2465        assert_eq!(s.capacity(), 0);
2466
2467        let mut s = HS::new();
2468        s.reserve(0);
2469        assert_eq!(s.capacity(), 0);
2470    }
2471
2472    #[test]
2473    fn test_disjoint() {
2474        let mut xs = HashSet::new();
2475        let mut ys = HashSet::new();
2476        assert!(xs.is_disjoint(&ys));
2477        assert!(ys.is_disjoint(&xs));
2478        assert!(xs.insert(5));
2479        assert!(ys.insert(11));
2480        assert!(xs.is_disjoint(&ys));
2481        assert!(ys.is_disjoint(&xs));
2482        assert!(xs.insert(7));
2483        assert!(xs.insert(19));
2484        assert!(xs.insert(4));
2485        assert!(ys.insert(2));
2486        assert!(ys.insert(-11));
2487        assert!(xs.is_disjoint(&ys));
2488        assert!(ys.is_disjoint(&xs));
2489        assert!(ys.insert(7));
2490        assert!(!xs.is_disjoint(&ys));
2491        assert!(!ys.is_disjoint(&xs));
2492    }
2493
2494    #[test]
2495    fn test_subset_and_superset() {
2496        let mut a = HashSet::new();
2497        assert!(a.insert(0));
2498        assert!(a.insert(5));
2499        assert!(a.insert(11));
2500        assert!(a.insert(7));
2501
2502        let mut b = HashSet::new();
2503        assert!(b.insert(0));
2504        assert!(b.insert(7));
2505        assert!(b.insert(19));
2506        assert!(b.insert(250));
2507        assert!(b.insert(11));
2508        assert!(b.insert(200));
2509
2510        assert!(!a.is_subset(&b));
2511        assert!(!a.is_superset(&b));
2512        assert!(!b.is_subset(&a));
2513        assert!(!b.is_superset(&a));
2514
2515        assert!(b.insert(5));
2516
2517        assert!(a.is_subset(&b));
2518        assert!(!a.is_superset(&b));
2519        assert!(!b.is_subset(&a));
2520        assert!(b.is_superset(&a));
2521    }
2522
2523    #[test]
2524    fn test_iterate() {
2525        let mut a = HashSet::new();
2526        for i in 0..32 {
2527            assert!(a.insert(i));
2528        }
2529        let mut observed: u32 = 0;
2530        for k in &a {
2531            observed |= 1 << *k;
2532        }
2533        assert_eq!(observed, 0xFFFF_FFFF);
2534    }
2535
2536    #[test]
2537    fn test_intersection() {
2538        let mut a = HashSet::new();
2539        let mut b = HashSet::new();
2540
2541        assert!(a.insert(11));
2542        assert!(a.insert(1));
2543        assert!(a.insert(3));
2544        assert!(a.insert(77));
2545        assert!(a.insert(103));
2546        assert!(a.insert(5));
2547        assert!(a.insert(-5));
2548
2549        assert!(b.insert(2));
2550        assert!(b.insert(11));
2551        assert!(b.insert(77));
2552        assert!(b.insert(-9));
2553        assert!(b.insert(-42));
2554        assert!(b.insert(5));
2555        assert!(b.insert(3));
2556
2557        let mut i = 0;
2558        let expected = [3, 5, 11, 77];
2559        for x in a.intersection(&b) {
2560            assert!(expected.contains(x));
2561            i += 1;
2562        }
2563        assert_eq!(i, expected.len());
2564    }
2565
2566    #[test]
2567    fn test_difference() {
2568        let mut a = HashSet::new();
2569        let mut b = HashSet::new();
2570
2571        assert!(a.insert(1));
2572        assert!(a.insert(3));
2573        assert!(a.insert(5));
2574        assert!(a.insert(9));
2575        assert!(a.insert(11));
2576
2577        assert!(b.insert(3));
2578        assert!(b.insert(9));
2579
2580        let mut i = 0;
2581        let expected = [1, 5, 11];
2582        for x in a.difference(&b) {
2583            assert!(expected.contains(x));
2584            i += 1;
2585        }
2586        assert_eq!(i, expected.len());
2587    }
2588
2589    #[test]
2590    fn test_symmetric_difference() {
2591        let mut a = HashSet::new();
2592        let mut b = HashSet::new();
2593
2594        assert!(a.insert(1));
2595        assert!(a.insert(3));
2596        assert!(a.insert(5));
2597        assert!(a.insert(9));
2598        assert!(a.insert(11));
2599
2600        assert!(b.insert(-2));
2601        assert!(b.insert(3));
2602        assert!(b.insert(9));
2603        assert!(b.insert(14));
2604        assert!(b.insert(22));
2605
2606        let mut i = 0;
2607        let expected = [-2, 1, 5, 11, 14, 22];
2608        for x in a.symmetric_difference(&b) {
2609            assert!(expected.contains(x));
2610            i += 1;
2611        }
2612        assert_eq!(i, expected.len());
2613    }
2614
2615    #[test]
2616    fn test_union() {
2617        let mut a = HashSet::new();
2618        let mut b = HashSet::new();
2619
2620        assert!(a.insert(1));
2621        assert!(a.insert(3));
2622        assert!(a.insert(5));
2623        assert!(a.insert(9));
2624        assert!(a.insert(11));
2625        assert!(a.insert(16));
2626        assert!(a.insert(19));
2627        assert!(a.insert(24));
2628
2629        assert!(b.insert(-2));
2630        assert!(b.insert(1));
2631        assert!(b.insert(5));
2632        assert!(b.insert(9));
2633        assert!(b.insert(13));
2634        assert!(b.insert(19));
2635
2636        let mut i = 0;
2637        let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24];
2638        for x in a.union(&b) {
2639            assert!(expected.contains(x));
2640            i += 1;
2641        }
2642        assert_eq!(i, expected.len());
2643    }
2644
2645    #[test]
2646    fn test_from_map() {
2647        let mut a = crate::HashMap::new();
2648        a.insert(1, ());
2649        a.insert(2, ());
2650        a.insert(3, ());
2651        a.insert(4, ());
2652
2653        let a: HashSet<_> = a.into();
2654
2655        assert_eq!(a.len(), 4);
2656        assert!(a.contains(&1));
2657        assert!(a.contains(&2));
2658        assert!(a.contains(&3));
2659        assert!(a.contains(&4));
2660    }
2661
2662    #[test]
2663    fn test_from_iter() {
2664        let xs = [1, 2, 2, 3, 4, 5, 6, 7, 8, 9];
2665
2666        let set: HashSet<_> = xs.iter().copied().collect();
2667
2668        for x in &xs {
2669            assert!(set.contains(x));
2670        }
2671
2672        assert_eq!(set.iter().len(), xs.len() - 1);
2673    }
2674
2675    #[test]
2676    fn test_move_iter() {
2677        let hs = {
2678            let mut hs = HashSet::new();
2679
2680            hs.insert('a');
2681            hs.insert('b');
2682
2683            hs
2684        };
2685
2686        let v = hs.into_iter().collect::<Vec<char>>();
2687        assert!(v == ['a', 'b'] || v == ['b', 'a']);
2688    }
2689
2690    #[test]
2691    fn test_eq() {
2692        // These constants once happened to expose a bug in insert().
2693        // I'm keeping them around to prevent a regression.
2694        let mut s1 = HashSet::new();
2695
2696        s1.insert(1);
2697        s1.insert(2);
2698        s1.insert(3);
2699
2700        let mut s2 = HashSet::new();
2701
2702        s2.insert(1);
2703        s2.insert(2);
2704
2705        assert!(s1 != s2);
2706
2707        s2.insert(3);
2708
2709        assert_eq!(s1, s2);
2710    }
2711
2712    #[test]
2713    fn test_show() {
2714        let mut set = HashSet::new();
2715        let empty = HashSet::<i32>::new();
2716
2717        set.insert(1);
2718        set.insert(2);
2719
2720        let set_str = format!("{set:?}");
2721
2722        assert!(set_str == "{1, 2}" || set_str == "{2, 1}");
2723        assert_eq!(format!("{empty:?}"), "{}");
2724    }
2725
2726    #[test]
2727    fn test_trivial_drain() {
2728        let mut s = HashSet::<i32>::new();
2729        for _ in s.drain() {}
2730        assert!(s.is_empty());
2731        drop(s);
2732
2733        let mut s = HashSet::<i32>::new();
2734        drop(s.drain());
2735        assert!(s.is_empty());
2736    }
2737
2738    #[test]
2739    fn test_drain() {
2740        let mut s: HashSet<_> = (1..100).collect();
2741
2742        // try this a bunch of times to make sure we don't screw up internal state.
2743        for _ in 0..20 {
2744            assert_eq!(s.len(), 99);
2745
2746            {
2747                let mut last_i = 0;
2748                let mut d = s.drain();
2749                for (i, x) in d.by_ref().take(50).enumerate() {
2750                    last_i = i;
2751                    assert!(x != 0);
2752                }
2753                assert_eq!(last_i, 49);
2754            }
2755
2756            assert!(s.is_empty(), "s should be empty!");
2757            // reset to try again.
2758            s.extend(1..100);
2759        }
2760    }
2761
2762    #[test]
2763    fn test_replace() {
2764        use core::hash;
2765
2766        #[derive(Debug)]
2767        struct Foo(&'static str, i32);
2768
2769        impl PartialEq for Foo {
2770            fn eq(&self, other: &Self) -> bool {
2771                self.0 == other.0
2772            }
2773        }
2774
2775        impl Eq for Foo {}
2776
2777        impl hash::Hash for Foo {
2778            fn hash<H: hash::Hasher>(&self, h: &mut H) {
2779                self.0.hash(h);
2780            }
2781        }
2782
2783        let mut s = HashSet::new();
2784        assert_eq!(s.replace(Foo("a", 1)), None);
2785        assert_eq!(s.len(), 1);
2786        assert_eq!(s.replace(Foo("a", 2)), Some(Foo("a", 1)));
2787        assert_eq!(s.len(), 1);
2788
2789        let mut it = s.iter();
2790        assert_eq!(it.next(), Some(&Foo("a", 2)));
2791        assert_eq!(it.next(), None);
2792    }
2793
2794    #[test]
2795    #[allow(clippy::needless_borrow)]
2796    fn test_extend_ref() {
2797        let mut a = HashSet::new();
2798        a.insert(1);
2799
2800        a.extend([2, 3, 4]);
2801
2802        assert_eq!(a.len(), 4);
2803        assert!(a.contains(&1));
2804        assert!(a.contains(&2));
2805        assert!(a.contains(&3));
2806        assert!(a.contains(&4));
2807
2808        let mut b = HashSet::new();
2809        b.insert(5);
2810        b.insert(6);
2811
2812        a.extend(&b);
2813
2814        assert_eq!(a.len(), 6);
2815        assert!(a.contains(&1));
2816        assert!(a.contains(&2));
2817        assert!(a.contains(&3));
2818        assert!(a.contains(&4));
2819        assert!(a.contains(&5));
2820        assert!(a.contains(&6));
2821    }
2822
2823    #[test]
2824    fn test_retain() {
2825        let xs = [1, 2, 3, 4, 5, 6];
2826        let mut set: HashSet<i32> = xs.iter().copied().collect();
2827        set.retain(|&k| k % 2 == 0);
2828        assert_eq!(set.len(), 3);
2829        assert!(set.contains(&2));
2830        assert!(set.contains(&4));
2831        assert!(set.contains(&6));
2832    }
2833
2834    #[test]
2835    fn test_extract_if() {
2836        {
2837            let mut set: HashSet<i32> = (0..8).collect();
2838            let drained = set.extract_if(|&k| k % 2 == 0);
2839            let mut out = drained.collect::<Vec<_>>();
2840            out.sort_unstable();
2841            assert_eq!(vec![0, 2, 4, 6], out);
2842            assert_eq!(set.len(), 4);
2843        }
2844        {
2845            let mut set: HashSet<i32> = (0..8).collect();
2846            set.extract_if(|&k| k % 2 == 0).for_each(drop);
2847            assert_eq!(set.len(), 4, "Removes non-matching items on drop");
2848        }
2849    }
2850
2851    #[test]
2852    fn test_const_with_hasher() {
2853        use core::hash::BuildHasher;
2854        use std::collections::hash_map::DefaultHasher;
2855
2856        #[derive(Clone)]
2857        struct MyHasher;
2858        impl BuildHasher for MyHasher {
2859            type Hasher = DefaultHasher;
2860
2861            fn build_hasher(&self) -> DefaultHasher {
2862                DefaultHasher::new()
2863            }
2864        }
2865
2866        const EMPTY_SET: HashSet<u32, MyHasher> = HashSet::with_hasher(MyHasher);
2867
2868        let mut set = EMPTY_SET;
2869        set.insert(19);
2870        assert!(set.contains(&19));
2871    }
2872
2873    #[test]
2874    fn rehash_in_place() {
2875        let mut set = HashSet::new();
2876
2877        for i in 0..224 {
2878            set.insert(i);
2879        }
2880
2881        assert_eq!(
2882            set.capacity(),
2883            224,
2884            "The set must be at or close to capacity to trigger a re hashing"
2885        );
2886
2887        for i in 100..1400 {
2888            set.remove(&(i - 100));
2889            set.insert(i);
2890        }
2891    }
2892
2893    #[test]
2894    fn collect() {
2895        // At the time of writing, this hits the ZST case in from_base_index
2896        // (and without the `map`, it does not).
2897        let mut _set: HashSet<_> = (0..3).map(|_| ()).collect();
2898    }
2899}