cairo_lang_utils/
unordered_hash_set.rs1use core::borrow::Borrow;
2use core::hash::{BuildHasher, Hash};
3use core::ops::Sub;
4#[cfg(feature = "std")]
5use std::collections::HashSet;
6#[cfg(feature = "std")]
7use std::collections::hash_map::RandomState;
8
9#[cfg(not(feature = "std"))]
10use hashbrown::HashSet;
11
12#[cfg(feature = "std")]
17#[derive(Clone, Debug)]
18pub struct UnorderedHashSet<Key, BH = RandomState>(HashSet<Key, BH>);
19#[cfg(not(feature = "std"))]
20#[derive(Clone, Debug)]
21pub struct UnorderedHashSet<Key, BH = hashbrown::DefaultHashBuilder>(HashSet<Key, BH>);
22
23#[cfg(feature = "salsa")]
27unsafe impl<Key: Eq + Hash, BH: BuildHasher> salsa::Update for UnorderedHashSet<Key, BH> {
28 unsafe fn maybe_update(old_pointer: *mut Self, new_set: Self) -> bool {
29 let old_set: &mut Self = unsafe { &mut *old_pointer };
30
31 if *old_set == new_set {
32 false
33 } else {
34 old_set.clear();
35 old_set.extend_unordered(new_set);
36 true
37 }
38 }
39}
40
41impl<K, BH: Default> Default for UnorderedHashSet<K, BH> {
42 #[cfg(feature = "std")]
43 fn default() -> Self {
44 Self(Default::default())
45 }
46 #[cfg(not(feature = "std"))]
47 fn default() -> Self {
48 Self(HashSet::with_hasher(Default::default()))
49 }
50}
51
52impl<K, BH> PartialEq for UnorderedHashSet<K, BH>
53where
54 K: Eq + Hash,
55 BH: BuildHasher,
56{
57 fn eq(&self, other: &Self) -> bool {
58 self.0 == other.0
59 }
60}
61
62impl<K, BH> Eq for UnorderedHashSet<K, BH>
63where
64 K: Eq + Hash,
65 BH: BuildHasher,
66{
67}
68
69impl<Key, BH> UnorderedHashSet<Key, BH> {
70 pub fn len(&self) -> usize {
72 self.0.len()
73 }
74
75 pub fn is_empty(&self) -> bool {
77 self.0.is_empty()
78 }
79
80 pub fn clear(&mut self) {
82 self.0.clear()
83 }
84}
85
86impl<Key: Hash + Eq, BH: BuildHasher> UnorderedHashSet<Key, BH> {
87 pub fn insert(&mut self, key: Key) -> bool {
91 self.0.insert(key)
92 }
93
94 pub fn remove<Q: ?Sized + Hash + Eq>(&mut self, value: &Q) -> bool
96 where
97 Key: Borrow<Q>,
98 {
99 self.0.remove(value)
100 }
101
102 pub fn extend<I: IntoIterator<Item = Key>>(&mut self, iter: I) {
104 self.0.extend(iter)
105 }
106
107 pub fn extend_unordered(&mut self, other: Self) {
109 self.0.extend(other.0)
110 }
111
112 pub fn contains<Q: ?Sized + Hash + Eq>(&self, value: &Q) -> bool
114 where
115 Key: Borrow<Q>,
116 {
117 self.0.contains(value)
118 }
119}
120
121impl<Key: Hash + Eq, BH: BuildHasher + Default> FromIterator<Key> for UnorderedHashSet<Key, BH> {
122 fn from_iter<T: IntoIterator<Item = Key>>(iter: T) -> Self {
123 Self(iter.into_iter().collect())
124 }
125}
126
127impl<'a, Key, BH> Sub<&'a UnorderedHashSet<Key, BH>> for &'a UnorderedHashSet<Key, BH>
128where
129 &'a HashSet<Key, BH>: Sub<Output = HashSet<Key, BH>>,
130{
131 type Output = UnorderedHashSet<Key, BH>;
132
133 fn sub(self, rhs: Self) -> Self::Output {
134 UnorderedHashSet::<Key, BH>(&self.0 - &rhs.0)
135 }
136}