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>(&self, value: &Q) -> bool
927    where
928        Q: ?Sized + 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>(&self, value: &Q) -> Option<&T>
954    where
955        Q: ?Sized + 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>(&mut self, value: &Q) -> Result<&T, Error>
1013    where
1014        Q: ?Sized + 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, F>(&mut self, value: &Q, f: F) -> Result<&T, Error>
1048    where
1049        Q: ?Sized + 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>(&mut self, value: &Q) -> bool
1282    where
1283        Q: ?Sized + 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>(&mut self, value: &Q) -> Option<T>
1309    where
1310        Q: ?Sized + 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::prelude::*;
1636    /// use rune::alloc::HashSet;
1637    ///
1638    /// let mut set = HashSet::new();
1639    /// set.try_insert("a".try_to_string()?)?;
1640    /// set.try_insert("b".try_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<K> ExactSizeIterator for Iter<'_, 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
1736    #[cfg_attr(feature = "inline-more", inline)]
1737    fn size_hint(&self) -> (usize, Option<usize>) {
1738        self.iter.size_hint()
1739    }
1740}
1741impl<K, A: Allocator> ExactSizeIterator for Drain<'_, K, A> {
1742    #[cfg_attr(feature = "inline-more", inline)]
1743    fn len(&self) -> usize {
1744        self.iter.len()
1745    }
1746}
1747impl<K, A: Allocator> FusedIterator for Drain<'_, K, A> {}
1748
1749impl<K: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, K, A> {
1750    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1751        let entries_iter = self.iter.iter().map(|(k, _)| k);
1752        f.debug_list().entries(entries_iter).finish()
1753    }
1754}
1755
1756impl<K, F, A: Allocator> Iterator for ExtractIf<'_, K, F, A>
1757where
1758    F: FnMut(&K) -> bool,
1759{
1760    type Item = K;
1761
1762    #[cfg_attr(feature = "inline-more", inline)]
1763    fn next(&mut self) -> Option<Self::Item> {
1764        let f = &mut self.f;
1765        let (k, _) = self.inner.next(&mut |k, _| f(k))?;
1766        Some(k)
1767    }
1768
1769    #[inline]
1770    fn size_hint(&self) -> (usize, Option<usize>) {
1771        (0, self.inner.iter.size_hint().1)
1772    }
1773}
1774
1775impl<K, F, A: Allocator> FusedIterator for ExtractIf<'_, K, F, A> where F: FnMut(&K) -> bool {}
1776
1777impl<T, S, A: Allocator> Clone for Intersection<'_, T, S, A> {
1778    #[cfg_attr(feature = "inline-more", inline)]
1779    fn clone(&self) -> Self {
1780        Intersection {
1781            iter: self.iter.clone(),
1782            ..*self
1783        }
1784    }
1785}
1786
1787impl<'a, T, S, A> Iterator for Intersection<'a, T, S, A>
1788where
1789    T: Eq + Hash,
1790    S: BuildHasher,
1791    A: Allocator,
1792{
1793    type Item = &'a T;
1794
1795    #[cfg_attr(feature = "inline-more", inline)]
1796    fn next(&mut self) -> Option<&'a T> {
1797        loop {
1798            let elt = self.iter.next()?;
1799            if self.other.contains(elt) {
1800                return Some(elt);
1801            }
1802        }
1803    }
1804
1805    #[cfg_attr(feature = "inline-more", inline)]
1806    fn size_hint(&self) -> (usize, Option<usize>) {
1807        let (_, upper) = self.iter.size_hint();
1808        (0, upper)
1809    }
1810}
1811
1812impl<T, S, A> fmt::Debug for Intersection<'_, T, S, A>
1813where
1814    T: fmt::Debug + Eq + Hash,
1815    S: BuildHasher,
1816    A: Allocator,
1817{
1818    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1819        f.debug_list().entries(self.clone()).finish()
1820    }
1821}
1822
1823impl<T, S, A> FusedIterator for Intersection<'_, T, S, A>
1824where
1825    T: Eq + Hash,
1826    S: BuildHasher,
1827    A: Allocator,
1828{
1829}
1830
1831impl<T, S, A: Allocator> Clone for Difference<'_, T, S, A> {
1832    #[cfg_attr(feature = "inline-more", inline)]
1833    fn clone(&self) -> Self {
1834        Difference {
1835            iter: self.iter.clone(),
1836            ..*self
1837        }
1838    }
1839}
1840
1841impl<'a, T, S, A> Iterator for Difference<'a, T, S, A>
1842where
1843    T: Eq + Hash,
1844    S: BuildHasher,
1845    A: Allocator,
1846{
1847    type Item = &'a T;
1848
1849    #[cfg_attr(feature = "inline-more", inline)]
1850    fn next(&mut self) -> Option<&'a T> {
1851        loop {
1852            let elt = self.iter.next()?;
1853            if !self.other.contains(elt) {
1854                return Some(elt);
1855            }
1856        }
1857    }
1858
1859    #[cfg_attr(feature = "inline-more", inline)]
1860    fn size_hint(&self) -> (usize, Option<usize>) {
1861        let (_, upper) = self.iter.size_hint();
1862        (0, upper)
1863    }
1864}
1865
1866impl<T, S, A> FusedIterator for Difference<'_, T, S, A>
1867where
1868    T: Eq + Hash,
1869    S: BuildHasher,
1870    A: Allocator,
1871{
1872}
1873
1874impl<T, S, A> fmt::Debug for Difference<'_, T, S, A>
1875where
1876    T: fmt::Debug + Eq + Hash,
1877    S: BuildHasher,
1878    A: Allocator,
1879{
1880    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1881        f.debug_list().entries(self.clone()).finish()
1882    }
1883}
1884
1885impl<T, S, A: Allocator> Clone for SymmetricDifference<'_, T, S, A> {
1886    #[cfg_attr(feature = "inline-more", inline)]
1887    fn clone(&self) -> Self {
1888        SymmetricDifference {
1889            iter: self.iter.clone(),
1890        }
1891    }
1892}
1893
1894impl<'a, T, S, A> Iterator for SymmetricDifference<'a, T, S, A>
1895where
1896    T: Eq + Hash,
1897    S: BuildHasher,
1898    A: Allocator,
1899{
1900    type Item = &'a T;
1901
1902    #[cfg_attr(feature = "inline-more", inline)]
1903    fn next(&mut self) -> Option<&'a T> {
1904        self.iter.next()
1905    }
1906    #[cfg_attr(feature = "inline-more", inline)]
1907    fn size_hint(&self) -> (usize, Option<usize>) {
1908        self.iter.size_hint()
1909    }
1910}
1911
1912impl<T, S, A> FusedIterator for SymmetricDifference<'_, T, S, A>
1913where
1914    T: Eq + Hash,
1915    S: BuildHasher,
1916    A: Allocator,
1917{
1918}
1919
1920impl<T, S, A> fmt::Debug for SymmetricDifference<'_, T, S, A>
1921where
1922    T: fmt::Debug + Eq + Hash,
1923    S: BuildHasher,
1924    A: Allocator,
1925{
1926    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1927        f.debug_list().entries(self.clone()).finish()
1928    }
1929}
1930
1931impl<T, S, A: Allocator> Clone for Union<'_, T, S, A> {
1932    #[cfg_attr(feature = "inline-more", inline)]
1933    fn clone(&self) -> Self {
1934        Union {
1935            iter: self.iter.clone(),
1936        }
1937    }
1938}
1939
1940impl<T, S, A> FusedIterator for Union<'_, T, S, A>
1941where
1942    T: Eq + Hash,
1943    S: BuildHasher,
1944    A: Allocator,
1945{
1946}
1947
1948impl<T, S, A> fmt::Debug for Union<'_, T, S, A>
1949where
1950    T: fmt::Debug + Eq + Hash,
1951    S: BuildHasher,
1952    A: Allocator,
1953{
1954    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1955        f.debug_list().entries(self.clone()).finish()
1956    }
1957}
1958
1959impl<'a, T, S, A> Iterator for Union<'a, T, S, A>
1960where
1961    T: Eq + Hash,
1962    S: BuildHasher,
1963    A: Allocator,
1964{
1965    type Item = &'a T;
1966
1967    #[cfg_attr(feature = "inline-more", inline)]
1968    fn next(&mut self) -> Option<&'a T> {
1969        self.iter.next()
1970    }
1971    #[cfg_attr(feature = "inline-more", inline)]
1972    fn size_hint(&self) -> (usize, Option<usize>) {
1973        self.iter.size_hint()
1974    }
1975}
1976
1977/// A view into a single entry in a set, which may either be vacant or occupied.
1978///
1979/// This `enum` is constructed from the [`entry`] method on [`HashSet`].
1980///
1981/// [`HashSet`]: struct.HashSet.html
1982/// [`entry`]: struct.HashSet.html#method.entry
1983///
1984/// # Examples
1985///
1986/// ```
1987/// use rune::alloc::{HashSet, Vec};
1988/// use rune::alloc::hash_set::{Entry, OccupiedEntry};
1989/// use rune::alloc::prelude::*;
1990///
1991/// let mut set = HashSet::new();
1992/// set.try_extend(["a", "b", "c"])?;
1993/// assert_eq!(set.len(), 3);
1994///
1995/// // Existing value (insert)
1996/// let entry: Entry<_, _> = set.entry("a");
1997/// let _raw_o: OccupiedEntry<_, _> = entry.try_insert()?;
1998/// assert_eq!(set.len(), 3);
1999/// // Nonexistent value (insert)
2000/// set.entry("d").try_insert()?;
2001///
2002/// // Existing value (or_try_insert)
2003/// set.entry("b").or_try_insert()?;
2004/// // Nonexistent value (or_try_insert)
2005/// set.entry("e").or_try_insert()?;
2006///
2007/// println!("Our HashSet: {:?}", set);
2008///
2009/// let mut vec: Vec<_> = set.iter().copied().try_collect()?;
2010/// // The `Iter` iterator produces items in arbitrary order, so the
2011/// // items must be sorted to test them against a sorted array.
2012/// vec.sort_unstable();
2013/// assert_eq!(vec, ["a", "b", "c", "d", "e"]);
2014/// # Ok::<_, rune::alloc::Error>(())
2015/// ```
2016pub enum Entry<'a, T, S, A = Global>
2017where
2018    A: Allocator,
2019{
2020    /// An occupied entry.
2021    ///
2022    /// # Examples
2023    ///
2024    /// ```
2025    /// use rune::alloc::hash_set::Entry;
2026    /// use rune::alloc::HashSet;
2027    ///
2028    /// let mut set: HashSet<_> = HashSet::try_from(["a", "b"])?;
2029    ///
2030    /// match set.entry("a") {
2031    ///     Entry::Vacant(_) => unreachable!(),
2032    ///     Entry::Occupied(_) => { }
2033    /// }
2034    /// # Ok::<_, rune::alloc::Error>(())
2035    /// ```
2036    Occupied(OccupiedEntry<'a, T, S, A>),
2037
2038    /// A vacant entry.
2039    ///
2040    /// # Examples
2041    ///
2042    /// ```
2043    /// use rune::alloc::hash_set::{Entry, HashSet};
2044    /// let mut set = HashSet::new();
2045    ///
2046    /// match set.entry("a") {
2047    ///     Entry::Occupied(_) => unreachable!(),
2048    ///     Entry::Vacant(_) => { }
2049    /// }
2050    /// # Ok::<_, rune::alloc::Error>(())
2051    /// ```
2052    Vacant(VacantEntry<'a, T, S, A>),
2053}
2054
2055impl<T: fmt::Debug, S, A: Allocator> fmt::Debug for Entry<'_, T, S, A> {
2056    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2057        match *self {
2058            Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
2059            Entry::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
2060        }
2061    }
2062}
2063
2064/// A view into an occupied entry in a `HashSet`.
2065/// It is part of the [`Entry`] enum.
2066///
2067/// [`Entry`]: enum.Entry.html
2068///
2069/// # Examples
2070///
2071/// ```
2072/// use rune::alloc::hash_set::{Entry, HashSet, OccupiedEntry};
2073/// use rune::alloc::prelude::*;
2074///
2075/// let mut set = HashSet::new();
2076/// set.try_extend(["a", "b", "c"])?;
2077///
2078/// let _entry_o: OccupiedEntry<_, _> = set.entry("a").try_insert()?;
2079/// assert_eq!(set.len(), 3);
2080///
2081/// // Existing key
2082/// match set.entry("a") {
2083///     Entry::Vacant(_) => unreachable!(),
2084///     Entry::Occupied(view) => {
2085///         assert_eq!(view.get(), &"a");
2086///     }
2087/// }
2088///
2089/// assert_eq!(set.len(), 3);
2090///
2091/// // Existing key (take)
2092/// match set.entry("c") {
2093///     Entry::Vacant(_) => unreachable!(),
2094///     Entry::Occupied(view) => {
2095///         assert_eq!(view.remove(), "c");
2096///     }
2097/// }
2098/// assert_eq!(set.get(&"c"), None);
2099/// assert_eq!(set.len(), 2);
2100/// # Ok::<_, rune::alloc::Error>(())
2101/// ```
2102pub struct OccupiedEntry<'a, T, S, A: Allocator = Global> {
2103    inner: map::OccupiedEntry<'a, T, (), S, A>,
2104}
2105
2106impl<T: fmt::Debug, S, A: Allocator> fmt::Debug for OccupiedEntry<'_, T, S, A> {
2107    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2108        f.debug_struct("OccupiedEntry")
2109            .field("value", self.get())
2110            .finish()
2111    }
2112}
2113
2114/// A view into a vacant entry in a `HashSet`.
2115/// It is part of the [`Entry`] enum.
2116///
2117/// [`Entry`]: enum.Entry.html
2118///
2119/// # Examples
2120///
2121/// ```
2122/// use rune::alloc::hash_set::{Entry, HashSet, VacantEntry};
2123///
2124/// let mut set = HashSet::<&str>::new();
2125///
2126/// let entry_v: VacantEntry<_, _> = match set.entry("a") {
2127///     Entry::Vacant(view) => view,
2128///     Entry::Occupied(_) => unreachable!(),
2129/// };
2130/// entry_v.try_insert()?;
2131/// assert!(set.contains("a") && set.len() == 1);
2132///
2133/// // Nonexistent key (try_insert)
2134/// match set.entry("b") {
2135///     Entry::Vacant(view) => view.try_insert()?,
2136///     Entry::Occupied(_) => unreachable!(),
2137/// }
2138/// assert!(set.contains("b") && set.len() == 2);
2139/// # Ok::<_, rune::alloc::Error>(())
2140/// ```
2141pub struct VacantEntry<'a, T, S, A: Allocator = Global> {
2142    inner: map::VacantEntry<'a, T, (), S, A>,
2143}
2144
2145impl<T: fmt::Debug, S, A: Allocator> fmt::Debug for VacantEntry<'_, T, S, A> {
2146    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2147        f.debug_tuple("VacantEntry").field(self.get()).finish()
2148    }
2149}
2150
2151impl<'a, T, S, A: Allocator> Entry<'a, T, S, A> {
2152    /// Sets the value of the entry, and returns an OccupiedEntry.
2153    ///
2154    /// # Examples
2155    ///
2156    /// ```
2157    /// use rune::alloc::HashSet;
2158    ///
2159    /// let mut set: HashSet<&str> = HashSet::new();
2160    /// let entry = set.entry("horseyland").try_insert()?;
2161    ///
2162    /// assert_eq!(entry.get(), &"horseyland");
2163    /// # Ok::<_, rune::alloc::Error>(())
2164    /// ```
2165    #[cfg_attr(feature = "inline-more", inline)]
2166    pub fn try_insert(self) -> Result<OccupiedEntry<'a, T, S, A>, Error>
2167    where
2168        T: Hash,
2169        S: BuildHasher,
2170    {
2171        match self {
2172            Entry::Occupied(entry) => Ok(entry),
2173            Entry::Vacant(entry) => entry.try_insert_entry(),
2174        }
2175    }
2176
2177    /// Ensures a value is in the entry by inserting if it was vacant.
2178    ///
2179    /// # Examples
2180    ///
2181    /// ```
2182    /// use rune::alloc::HashSet;
2183    ///
2184    /// let mut set: HashSet<&str> = HashSet::new();
2185    ///
2186    /// // nonexistent key
2187    /// set.entry("poneyland").or_try_insert()?;
2188    /// assert!(set.contains("poneyland"));
2189    ///
2190    /// // existing key
2191    /// set.entry("poneyland").or_try_insert()?;
2192    /// assert!(set.contains("poneyland"));
2193    /// assert_eq!(set.len(), 1);
2194    /// # Ok::<_, rune::alloc::Error>(())
2195    /// ```
2196    #[cfg_attr(feature = "inline-more", inline)]
2197    pub fn or_try_insert(self) -> Result<(), Error>
2198    where
2199        T: Hash,
2200        S: BuildHasher,
2201    {
2202        if let Entry::Vacant(entry) = self {
2203            entry.try_insert()?;
2204        }
2205
2206        Ok(())
2207    }
2208
2209    /// Returns a reference to this entry's value.
2210    ///
2211    /// # Examples
2212    ///
2213    /// ```
2214    /// use rune::alloc::HashSet;
2215    ///
2216    /// let mut set: HashSet<&str> = HashSet::new();
2217    /// set.entry("poneyland").or_try_insert()?;
2218    /// // existing key
2219    /// assert_eq!(set.entry("poneyland").get(), &"poneyland");
2220    /// // nonexistent key
2221    /// assert_eq!(set.entry("horseland").get(), &"horseland");
2222    /// # Ok::<_, rune::alloc::Error>(())
2223    /// ```
2224    #[cfg_attr(feature = "inline-more", inline)]
2225    pub fn get(&self) -> &T {
2226        match *self {
2227            Entry::Occupied(ref entry) => entry.get(),
2228            Entry::Vacant(ref entry) => entry.get(),
2229        }
2230    }
2231}
2232
2233impl<T, S, A: Allocator> OccupiedEntry<'_, T, S, A> {
2234    /// Gets a reference to the value in the entry.
2235    ///
2236    /// # Examples
2237    ///
2238    /// ```
2239    /// use rune::alloc::hash_set::{Entry, HashSet};
2240    ///
2241    /// let mut set: HashSet<&str> = HashSet::new();
2242    /// set.entry("poneyland").or_try_insert()?;
2243    ///
2244    /// match set.entry("poneyland") {
2245    ///     Entry::Vacant(_) => panic!(),
2246    ///     Entry::Occupied(entry) => assert_eq!(entry.get(), &"poneyland"),
2247    /// }
2248    /// # Ok::<_, rune::alloc::Error>(())
2249    /// ```
2250    #[cfg_attr(feature = "inline-more", inline)]
2251    pub fn get(&self) -> &T {
2252        self.inner.key()
2253    }
2254
2255    /// Takes the value out of the entry, and returns it.
2256    /// Keeps the allocated memory for reuse.
2257    ///
2258    /// # Examples
2259    ///
2260    /// ```
2261    /// use rune::alloc::HashSet;
2262    /// use rune::alloc::hash_set::Entry;
2263    ///
2264    /// let mut set: HashSet<&str> = HashSet::new();
2265    /// // The set is empty
2266    /// assert!(set.is_empty() && set.capacity() == 0);
2267    ///
2268    /// set.entry("poneyland").or_try_insert()?;
2269    /// let capacity_before_remove = set.capacity();
2270    ///
2271    /// if let Entry::Occupied(o) = set.entry("poneyland") {
2272    ///     assert_eq!(o.remove(), "poneyland");
2273    /// }
2274    ///
2275    /// assert_eq!(set.contains("poneyland"), false);
2276    /// // Now set hold none elements but capacity is equal to the old one
2277    /// assert!(set.len() == 0 && set.capacity() == capacity_before_remove);
2278    /// # Ok::<_, rune::alloc::Error>(())
2279    /// ```
2280    #[cfg_attr(feature = "inline-more", inline)]
2281    pub fn remove(self) -> T {
2282        self.inner.remove_entry().0
2283    }
2284
2285    /// Replaces the entry, returning the old value. The new value in the hash
2286    /// map will be the value used to create this entry.
2287    ///
2288    /// # Panics
2289    ///
2290    /// Will panic if this OccupiedEntry was created through
2291    /// [`Entry::try_insert`].
2292    ///
2293    /// # Examples
2294    ///
2295    /// ```
2296    /// use rune::alloc::hash_set::{Entry, HashSet};
2297    /// use std::rc::Rc;
2298    ///
2299    /// let mut set: HashSet<Rc<String>> = HashSet::new();
2300    /// let key_one = Rc::new("Stringthing".to_string());
2301    /// let key_two = Rc::new("Stringthing".to_string());
2302    ///
2303    /// set.try_insert(key_one.clone())?;
2304    /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
2305    ///
2306    /// match set.entry(key_two.clone()) {
2307    ///     Entry::Occupied(entry) => {
2308    ///         let old_key: Rc<String> = entry.replace();
2309    ///         assert!(Rc::ptr_eq(&key_one, &old_key));
2310    ///     }
2311    ///     Entry::Vacant(_) => panic!(),
2312    /// }
2313    ///
2314    /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
2315    /// assert!(set.contains(&"Stringthing".to_owned()));
2316    /// # Ok::<_, rune::alloc::Error>(())
2317    /// ```
2318    #[cfg_attr(feature = "inline-more", inline)]
2319    pub fn replace(self) -> T {
2320        self.inner.replace_key()
2321    }
2322}
2323
2324impl<'a, T, S, A: Allocator> VacantEntry<'a, T, S, A> {
2325    /// Gets a reference to the value that would be used when inserting
2326    /// through the `VacantEntry`.
2327    ///
2328    /// # Examples
2329    ///
2330    /// ```
2331    /// use rune::alloc::HashSet;
2332    ///
2333    /// let mut set: HashSet<&str> = HashSet::new();
2334    /// assert_eq!(set.entry("poneyland").get(), &"poneyland");
2335    /// ```
2336    #[cfg_attr(feature = "inline-more", inline)]
2337    pub fn get(&self) -> &T {
2338        self.inner.key()
2339    }
2340
2341    /// Take ownership of the value.
2342    ///
2343    /// # Examples
2344    ///
2345    /// ```
2346    /// use rune::alloc::hash_set::{Entry, HashSet};
2347    ///
2348    /// let mut set = HashSet::new();
2349    ///
2350    /// match set.entry("poneyland") {
2351    ///     Entry::Occupied(_) => panic!(),
2352    ///     Entry::Vacant(v) => assert_eq!(v.into_value(), "poneyland"),
2353    /// }
2354    /// ```
2355    #[cfg_attr(feature = "inline-more", inline)]
2356    pub fn into_value(self) -> T {
2357        self.inner.into_key()
2358    }
2359
2360    /// Sets the value of the entry with the VacantEntry's value.
2361    ///
2362    /// # Examples
2363    ///
2364    /// ```
2365    /// use rune::alloc::HashSet;
2366    /// use rune::alloc::hash_set::Entry;
2367    ///
2368    /// let mut set: HashSet<&str> = HashSet::new();
2369    ///
2370    /// if let Entry::Vacant(o) = set.entry("poneyland") {
2371    ///     o.try_insert()?;
2372    /// }
2373    /// assert!(set.contains("poneyland"));
2374    /// # Ok::<_, rune::alloc::Error>(())
2375    /// ```
2376    #[cfg_attr(feature = "inline-more", inline)]
2377    pub fn try_insert(self) -> Result<(), Error>
2378    where
2379        T: Hash,
2380        S: BuildHasher,
2381    {
2382        self.inner.try_insert(())?;
2383        Ok(())
2384    }
2385
2386    #[cfg_attr(feature = "inline-more", inline)]
2387    fn try_insert_entry(self) -> Result<OccupiedEntry<'a, T, S, A>, Error>
2388    where
2389        T: Hash,
2390        S: BuildHasher,
2391    {
2392        Ok(OccupiedEntry {
2393            inner: self.inner.try_insert_entry(())?,
2394        })
2395    }
2396}
2397
2398#[allow(dead_code)]
2399fn assert_covariance() {
2400    fn set<'new>(v: HashSet<&'static str>) -> HashSet<&'new str> {
2401        v
2402    }
2403    fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> {
2404        v
2405    }
2406    fn into_iter<'new, A: Allocator>(v: IntoIter<&'static str, A>) -> IntoIter<&'new str, A> {
2407        v
2408    }
2409    fn difference<'a, 'new, A: Allocator>(
2410        v: Difference<'a, &'static str, DefaultHashBuilder, A>,
2411    ) -> Difference<'a, &'new str, DefaultHashBuilder, A> {
2412        v
2413    }
2414    fn symmetric_difference<'a, 'new, A: Allocator>(
2415        v: SymmetricDifference<'a, &'static str, DefaultHashBuilder, A>,
2416    ) -> SymmetricDifference<'a, &'new str, DefaultHashBuilder, A> {
2417        v
2418    }
2419    fn intersection<'a, 'new, A: Allocator>(
2420        v: Intersection<'a, &'static str, DefaultHashBuilder, A>,
2421    ) -> Intersection<'a, &'new str, DefaultHashBuilder, A> {
2422        v
2423    }
2424    fn union<'a, 'new, A: Allocator>(
2425        v: Union<'a, &'static str, DefaultHashBuilder, A>,
2426    ) -> Union<'a, &'new str, DefaultHashBuilder, A> {
2427        v
2428    }
2429    fn drain<'new, A: Allocator>(d: Drain<'static, &'static str, A>) -> Drain<'new, &'new str, A> {
2430        d
2431    }
2432}
2433
2434#[cfg(test)]
2435mod test_set {
2436    use super::super::map::DefaultHashBuilder;
2437    use super::HashSet;
2438    use rust_alloc::vec::Vec;
2439    use rust_alloc::{format, vec};
2440
2441    #[test]
2442    fn test_zero_capacities() {
2443        type HS = HashSet<i32>;
2444
2445        let s = HS::new();
2446        assert_eq!(s.capacity(), 0);
2447
2448        let s = HS::default();
2449        assert_eq!(s.capacity(), 0);
2450
2451        let s = HS::with_hasher(DefaultHashBuilder::default());
2452        assert_eq!(s.capacity(), 0);
2453
2454        let s = HS::with_capacity(0);
2455        assert_eq!(s.capacity(), 0);
2456
2457        let s = HS::with_capacity_and_hasher(0, DefaultHashBuilder::default());
2458        assert_eq!(s.capacity(), 0);
2459
2460        let mut s = HS::new();
2461        s.insert(1);
2462        s.insert(2);
2463        s.remove(&1);
2464        s.remove(&2);
2465        s.shrink_to_fit();
2466        assert_eq!(s.capacity(), 0);
2467
2468        let mut s = HS::new();
2469        s.reserve(0);
2470        assert_eq!(s.capacity(), 0);
2471    }
2472
2473    #[test]
2474    fn test_disjoint() {
2475        let mut xs = HashSet::new();
2476        let mut ys = HashSet::new();
2477        assert!(xs.is_disjoint(&ys));
2478        assert!(ys.is_disjoint(&xs));
2479        assert!(xs.insert(5));
2480        assert!(ys.insert(11));
2481        assert!(xs.is_disjoint(&ys));
2482        assert!(ys.is_disjoint(&xs));
2483        assert!(xs.insert(7));
2484        assert!(xs.insert(19));
2485        assert!(xs.insert(4));
2486        assert!(ys.insert(2));
2487        assert!(ys.insert(-11));
2488        assert!(xs.is_disjoint(&ys));
2489        assert!(ys.is_disjoint(&xs));
2490        assert!(ys.insert(7));
2491        assert!(!xs.is_disjoint(&ys));
2492        assert!(!ys.is_disjoint(&xs));
2493    }
2494
2495    #[test]
2496    fn test_subset_and_superset() {
2497        let mut a = HashSet::new();
2498        assert!(a.insert(0));
2499        assert!(a.insert(5));
2500        assert!(a.insert(11));
2501        assert!(a.insert(7));
2502
2503        let mut b = HashSet::new();
2504        assert!(b.insert(0));
2505        assert!(b.insert(7));
2506        assert!(b.insert(19));
2507        assert!(b.insert(250));
2508        assert!(b.insert(11));
2509        assert!(b.insert(200));
2510
2511        assert!(!a.is_subset(&b));
2512        assert!(!a.is_superset(&b));
2513        assert!(!b.is_subset(&a));
2514        assert!(!b.is_superset(&a));
2515
2516        assert!(b.insert(5));
2517
2518        assert!(a.is_subset(&b));
2519        assert!(!a.is_superset(&b));
2520        assert!(!b.is_subset(&a));
2521        assert!(b.is_superset(&a));
2522    }
2523
2524    #[test]
2525    fn test_iterate() {
2526        let mut a = HashSet::new();
2527        for i in 0..32 {
2528            assert!(a.insert(i));
2529        }
2530        let mut observed: u32 = 0;
2531        for k in &a {
2532            observed |= 1 << *k;
2533        }
2534        assert_eq!(observed, 0xFFFF_FFFF);
2535    }
2536
2537    #[test]
2538    fn test_intersection() {
2539        let mut a = HashSet::new();
2540        let mut b = HashSet::new();
2541
2542        assert!(a.insert(11));
2543        assert!(a.insert(1));
2544        assert!(a.insert(3));
2545        assert!(a.insert(77));
2546        assert!(a.insert(103));
2547        assert!(a.insert(5));
2548        assert!(a.insert(-5));
2549
2550        assert!(b.insert(2));
2551        assert!(b.insert(11));
2552        assert!(b.insert(77));
2553        assert!(b.insert(-9));
2554        assert!(b.insert(-42));
2555        assert!(b.insert(5));
2556        assert!(b.insert(3));
2557
2558        let mut i = 0;
2559        let expected = [3, 5, 11, 77];
2560        for x in a.intersection(&b) {
2561            assert!(expected.contains(x));
2562            i += 1;
2563        }
2564        assert_eq!(i, expected.len());
2565    }
2566
2567    #[test]
2568    fn test_difference() {
2569        let mut a = HashSet::new();
2570        let mut b = HashSet::new();
2571
2572        assert!(a.insert(1));
2573        assert!(a.insert(3));
2574        assert!(a.insert(5));
2575        assert!(a.insert(9));
2576        assert!(a.insert(11));
2577
2578        assert!(b.insert(3));
2579        assert!(b.insert(9));
2580
2581        let mut i = 0;
2582        let expected = [1, 5, 11];
2583        for x in a.difference(&b) {
2584            assert!(expected.contains(x));
2585            i += 1;
2586        }
2587        assert_eq!(i, expected.len());
2588    }
2589
2590    #[test]
2591    fn test_symmetric_difference() {
2592        let mut a = HashSet::new();
2593        let mut b = HashSet::new();
2594
2595        assert!(a.insert(1));
2596        assert!(a.insert(3));
2597        assert!(a.insert(5));
2598        assert!(a.insert(9));
2599        assert!(a.insert(11));
2600
2601        assert!(b.insert(-2));
2602        assert!(b.insert(3));
2603        assert!(b.insert(9));
2604        assert!(b.insert(14));
2605        assert!(b.insert(22));
2606
2607        let mut i = 0;
2608        let expected = [-2, 1, 5, 11, 14, 22];
2609        for x in a.symmetric_difference(&b) {
2610            assert!(expected.contains(x));
2611            i += 1;
2612        }
2613        assert_eq!(i, expected.len());
2614    }
2615
2616    #[test]
2617    fn test_union() {
2618        let mut a = HashSet::new();
2619        let mut b = HashSet::new();
2620
2621        assert!(a.insert(1));
2622        assert!(a.insert(3));
2623        assert!(a.insert(5));
2624        assert!(a.insert(9));
2625        assert!(a.insert(11));
2626        assert!(a.insert(16));
2627        assert!(a.insert(19));
2628        assert!(a.insert(24));
2629
2630        assert!(b.insert(-2));
2631        assert!(b.insert(1));
2632        assert!(b.insert(5));
2633        assert!(b.insert(9));
2634        assert!(b.insert(13));
2635        assert!(b.insert(19));
2636
2637        let mut i = 0;
2638        let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24];
2639        for x in a.union(&b) {
2640            assert!(expected.contains(x));
2641            i += 1;
2642        }
2643        assert_eq!(i, expected.len());
2644    }
2645
2646    #[test]
2647    fn test_from_map() {
2648        let mut a = crate::HashMap::new();
2649        a.insert(1, ());
2650        a.insert(2, ());
2651        a.insert(3, ());
2652        a.insert(4, ());
2653
2654        let a: HashSet<_> = a.into();
2655
2656        assert_eq!(a.len(), 4);
2657        assert!(a.contains(&1));
2658        assert!(a.contains(&2));
2659        assert!(a.contains(&3));
2660        assert!(a.contains(&4));
2661    }
2662
2663    #[test]
2664    fn test_from_iter() {
2665        let xs = [1, 2, 2, 3, 4, 5, 6, 7, 8, 9];
2666
2667        let set: HashSet<_> = xs.iter().copied().collect();
2668
2669        for x in &xs {
2670            assert!(set.contains(x));
2671        }
2672
2673        assert_eq!(set.iter().len(), xs.len() - 1);
2674    }
2675
2676    #[test]
2677    fn test_move_iter() {
2678        let hs = {
2679            let mut hs = HashSet::new();
2680
2681            hs.insert('a');
2682            hs.insert('b');
2683
2684            hs
2685        };
2686
2687        let v = hs.into_iter().collect::<Vec<char>>();
2688        assert!(v == ['a', 'b'] || v == ['b', 'a']);
2689    }
2690
2691    #[test]
2692    fn test_eq() {
2693        // These constants once happened to expose a bug in insert().
2694        // I'm keeping them around to prevent a regression.
2695        let mut s1 = HashSet::new();
2696
2697        s1.insert(1);
2698        s1.insert(2);
2699        s1.insert(3);
2700
2701        let mut s2 = HashSet::new();
2702
2703        s2.insert(1);
2704        s2.insert(2);
2705
2706        assert!(s1 != s2);
2707
2708        s2.insert(3);
2709
2710        assert_eq!(s1, s2);
2711    }
2712
2713    #[test]
2714    fn test_show() {
2715        let mut set = HashSet::new();
2716        let empty = HashSet::<i32>::new();
2717
2718        set.insert(1);
2719        set.insert(2);
2720
2721        let set_str = format!("{set:?}");
2722
2723        assert!(set_str == "{1, 2}" || set_str == "{2, 1}");
2724        assert_eq!(format!("{empty:?}"), "{}");
2725    }
2726
2727    #[test]
2728    fn test_trivial_drain() {
2729        let mut s = HashSet::<i32>::new();
2730        for _ in s.drain() {}
2731        assert!(s.is_empty());
2732        drop(s);
2733
2734        let mut s = HashSet::<i32>::new();
2735        drop(s.drain());
2736        assert!(s.is_empty());
2737    }
2738
2739    #[test]
2740    fn test_drain() {
2741        let mut s: HashSet<_> = (1..100).collect();
2742
2743        // try this a bunch of times to make sure we don't screw up internal state.
2744        for _ in 0..20 {
2745            assert_eq!(s.len(), 99);
2746
2747            {
2748                let mut last_i = 0;
2749                let mut d = s.drain();
2750                for (i, x) in d.by_ref().take(50).enumerate() {
2751                    last_i = i;
2752                    assert!(x != 0);
2753                }
2754                assert_eq!(last_i, 49);
2755            }
2756
2757            assert!(s.is_empty(), "s should be empty!");
2758            // reset to try again.
2759            s.extend(1..100);
2760        }
2761    }
2762
2763    #[test]
2764    fn test_replace() {
2765        use core::hash;
2766
2767        #[derive(Debug)]
2768        struct Foo(&'static str, #[allow(unused)] i32);
2769
2770        impl PartialEq for Foo {
2771            fn eq(&self, other: &Self) -> bool {
2772                self.0 == other.0
2773            }
2774        }
2775
2776        impl Eq for Foo {}
2777
2778        impl hash::Hash for Foo {
2779            fn hash<H: hash::Hasher>(&self, h: &mut H) {
2780                self.0.hash(h);
2781            }
2782        }
2783
2784        let mut s = HashSet::new();
2785        assert_eq!(s.replace(Foo("a", 1)), None);
2786        assert_eq!(s.len(), 1);
2787        assert_eq!(s.replace(Foo("a", 2)), Some(Foo("a", 1)));
2788        assert_eq!(s.len(), 1);
2789
2790        let mut it = s.iter();
2791        assert_eq!(it.next(), Some(&Foo("a", 2)));
2792        assert_eq!(it.next(), None);
2793    }
2794
2795    #[test]
2796    #[allow(clippy::needless_borrow)]
2797    fn test_extend_ref() {
2798        let mut a = HashSet::new();
2799        a.insert(1);
2800
2801        a.extend([2, 3, 4]);
2802
2803        assert_eq!(a.len(), 4);
2804        assert!(a.contains(&1));
2805        assert!(a.contains(&2));
2806        assert!(a.contains(&3));
2807        assert!(a.contains(&4));
2808
2809        let mut b = HashSet::new();
2810        b.insert(5);
2811        b.insert(6);
2812
2813        a.extend(&b);
2814
2815        assert_eq!(a.len(), 6);
2816        assert!(a.contains(&1));
2817        assert!(a.contains(&2));
2818        assert!(a.contains(&3));
2819        assert!(a.contains(&4));
2820        assert!(a.contains(&5));
2821        assert!(a.contains(&6));
2822    }
2823
2824    #[test]
2825    fn test_retain() {
2826        let xs = [1, 2, 3, 4, 5, 6];
2827        let mut set: HashSet<i32> = xs.iter().copied().collect();
2828        set.retain(|&k| k % 2 == 0);
2829        assert_eq!(set.len(), 3);
2830        assert!(set.contains(&2));
2831        assert!(set.contains(&4));
2832        assert!(set.contains(&6));
2833    }
2834
2835    #[test]
2836    fn test_extract_if() {
2837        {
2838            let mut set: HashSet<i32> = (0..8).collect();
2839            let drained = set.extract_if(|&k| k % 2 == 0);
2840            let mut out = drained.collect::<Vec<_>>();
2841            out.sort_unstable();
2842            assert_eq!(vec![0, 2, 4, 6], out);
2843            assert_eq!(set.len(), 4);
2844        }
2845        {
2846            let mut set: HashSet<i32> = (0..8).collect();
2847            set.extract_if(|&k| k % 2 == 0).for_each(drop);
2848            assert_eq!(set.len(), 4, "Removes non-matching items on drop");
2849        }
2850    }
2851
2852    #[test]
2853    fn test_const_with_hasher() {
2854        use core::hash::BuildHasher;
2855        use std::collections::hash_map::DefaultHasher;
2856
2857        #[derive(Clone)]
2858        struct MyHasher;
2859        impl BuildHasher for MyHasher {
2860            type Hasher = DefaultHasher;
2861
2862            fn build_hasher(&self) -> DefaultHasher {
2863                DefaultHasher::new()
2864            }
2865        }
2866
2867        const EMPTY_SET: HashSet<u32, MyHasher> = HashSet::with_hasher(MyHasher);
2868
2869        let mut set = EMPTY_SET;
2870        set.insert(19);
2871        assert!(set.contains(&19));
2872    }
2873
2874    #[test]
2875    fn rehash_in_place() {
2876        let mut set = HashSet::new();
2877
2878        for i in 0..224 {
2879            set.insert(i);
2880        }
2881
2882        assert_eq!(
2883            set.capacity(),
2884            224,
2885            "The set must be at or close to capacity to trigger a re hashing"
2886        );
2887
2888        for i in 100..1400 {
2889            set.remove(&(i - 100));
2890            set.insert(i);
2891        }
2892    }
2893
2894    #[test]
2895    fn collect() {
2896        // At the time of writing, this hits the ZST case in from_base_index
2897        // (and without the `map`, it does not).
2898        let mut _set: HashSet<_> = (0..3).map(|_| ()).collect();
2899    }
2900}