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