1use crate::HashTrieMap;
2use crate::map::hash_trie_map;
3use crate::utils::DefaultBuildHasher;
4use archery::{ArcTK, RcK, SharedPointerKind};
5use core::borrow::Borrow;
6use core::fmt::Display;
7use core::hash::BuildHasher;
8use core::hash::Hash;
9use core::iter::FromIterator;
10
11pub type Iter<'a, T, P> = hash_trie_map::IterKeys<'a, T, (), P>;
13
14#[macro_export]
27macro_rules! ht_set {
28 ($($e:expr),*) => {
29 {
30 #[allow(unused_mut)]
31 let mut s = $crate::HashTrieSet::new();
32 $(
33 s.insert_mut($e);
34 )*
35 s
36 }
37 };
38}
39
40#[macro_export]
54macro_rules! ht_set_sync {
55 ($($e:expr),*) => {
56 {
57 #[allow(unused_mut)]
58 let mut s = $crate::HashTrieSet::new_sync();
59 $(
60 s.insert_mut($e);
61 )*
62 s
63 }
64 };
65}
66
67#[derive(Debug)]
93pub struct HashTrieSet<T, P = RcK, H: BuildHasher = DefaultBuildHasher>
94where
95 T: Eq + Hash,
96 H: Clone,
97 P: SharedPointerKind,
98{
99 map: HashTrieMap<T, (), P, H>,
100}
101
102pub type HashTrieSetSync<T, H = DefaultBuildHasher> = HashTrieSet<T, ArcTK, H>;
103
104impl<T> HashTrieSet<T, RcK, DefaultBuildHasher>
105where
106 T: Eq + Hash,
107{
108 #[must_use]
109 pub fn new() -> HashTrieSet<T> {
110 HashTrieSet {
111 map: HashTrieMap::new_with_hasher_and_ptr_kind(DefaultBuildHasher::default()),
112 }
113 }
114
115 #[must_use]
116 pub fn new_with_degree(degree: u8) -> HashTrieSet<T> {
117 HashTrieSet::new_with_hasher_and_degree_and_ptr_kind(DefaultBuildHasher::default(), degree)
118 }
119}
120
121impl<T> HashTrieSetSync<T>
122where
123 T: Eq + Hash,
124{
125 #[must_use]
126 pub fn new_sync() -> HashTrieSetSync<T> {
127 HashTrieSet {
128 map: HashTrieMap::new_with_hasher_and_ptr_kind(DefaultBuildHasher::default()),
129 }
130 }
131
132 #[must_use]
133 pub fn new_with_degree_sync(degree: u8) -> HashTrieSetSync<T> {
134 HashTrieSet::new_with_hasher_and_degree_and_ptr_kind(DefaultBuildHasher::default(), degree)
135 }
136}
137
138impl<T, P, H: BuildHasher> HashTrieSet<T, P, H>
139where
140 T: Eq + Hash,
141 H: Clone,
142 P: SharedPointerKind,
143{
144 #[must_use]
145 pub fn new_with_hasher_with_ptr_kind(hasher_builder: H) -> HashTrieSet<T, P, H> {
146 HashTrieSet { map: HashTrieMap::new_with_hasher_and_ptr_kind(hasher_builder) }
147 }
148
149 #[must_use]
150 pub fn new_with_hasher_and_degree_and_ptr_kind(
151 hasher_builder: H,
152 degree: u8,
153 ) -> HashTrieSet<T, P, H> {
154 HashTrieSet {
155 map: HashTrieMap::new_with_hasher_and_degree_and_ptr_kind(hasher_builder, degree),
156 }
157 }
158
159 #[must_use]
160 pub fn insert(&self, v: T) -> HashTrieSet<T, P, H> {
161 HashTrieSet { map: self.map.insert(v, ()) }
162 }
163
164 pub fn insert_mut(&mut self, v: T) {
165 self.map.insert_mut(v, ());
166 }
167
168 #[must_use]
169 pub fn remove<V: ?Sized>(&self, v: &V) -> HashTrieSet<T, P, H>
170 where
171 T: Borrow<V>,
172 V: Hash + Eq,
173 {
174 HashTrieSet { map: self.map.remove(v) }
175 }
176
177 pub fn remove_mut<V: ?Sized>(&mut self, v: &V) -> bool
178 where
179 T: Borrow<V>,
180 V: Hash + Eq,
181 {
182 self.map.remove_mut(v)
183 }
184
185 #[must_use]
186 pub fn get<V: ?Sized>(&self, v: &V) -> Option<&T>
187 where
188 T: Borrow<V>,
189 V: Hash + Eq,
190 {
191 self.map.get_key_value(v).map(|(k, ())| k)
192 }
193
194 #[must_use]
195 pub fn contains<V: ?Sized>(&self, v: &V) -> bool
196 where
197 T: Borrow<V>,
198 V: Hash + Eq,
199 {
200 self.map.contains_key(v)
201 }
202
203 #[must_use]
204 pub fn is_disjoint<HO: BuildHasher + Clone>(&self, other: &HashTrieSet<T, P, HO>) -> bool {
205 self.iter().all(|v| !other.contains(v))
206 }
207
208 fn ptr_eq<PO: SharedPointerKind, HO: BuildHasher + Clone>(
213 &self,
214 other: &HashTrieSet<T, PO, HO>,
215 ) -> bool {
216 self.map.ptr_eq(&other.map)
217 }
218
219 #[must_use]
220 pub fn is_subset<HO: BuildHasher + Clone>(&self, other: &HashTrieSet<T, P, HO>) -> bool {
221 if self.ptr_eq(other) {
222 return true;
223 }
224
225 self.size() <= other.size() && self.iter().all(|v| other.contains(v))
226 }
227
228 #[must_use]
229 pub fn is_superset<HO: BuildHasher + Clone>(&self, other: &HashTrieSet<T, P, HO>) -> bool {
230 other.is_subset(self)
231 }
232
233 #[must_use]
234 #[inline]
235 pub fn size(&self) -> usize {
236 self.map.size()
237 }
238
239 #[must_use]
240 #[inline]
241 pub fn is_empty(&self) -> bool {
242 self.size() == 0
243 }
244
245 #[allow(clippy::iter_without_into_iter)]
246 pub fn iter(&self) -> Iter<'_, T, P> {
247 self.map.keys()
248 }
249}
250
251impl<T, P, H: BuildHasher> Clone for HashTrieSet<T, P, H>
252where
253 T: Eq + Hash,
254 H: Clone,
255 P: SharedPointerKind,
256{
257 fn clone(&self) -> HashTrieSet<T, P, H> {
258 HashTrieSet { map: self.map.clone() }
259 }
260}
261
262impl<T, P, H: BuildHasher> Default for HashTrieSet<T, P, H>
263where
264 T: Eq + Hash,
265 H: Default + Clone,
266 P: SharedPointerKind,
267{
268 fn default() -> HashTrieSet<T, P, H> {
269 HashTrieSet::new_with_hasher_with_ptr_kind(H::default())
270 }
271}
272
273impl<T: Eq, P, PO, H: BuildHasher> PartialEq<HashTrieSet<T, PO, H>> for HashTrieSet<T, P, H>
274where
275 T: Hash,
276 H: Clone,
277 P: SharedPointerKind,
278 PO: SharedPointerKind,
279{
280 fn eq(&self, other: &HashTrieSet<T, PO, H>) -> bool {
281 self.map.eq(&other.map)
282 }
283}
284
285impl<T: Eq, P, H: BuildHasher> Eq for HashTrieSet<T, P, H>
286where
287 T: Hash,
288 H: Clone,
289 P: SharedPointerKind,
290{
291}
292
293impl<T, P, H: BuildHasher> Display for HashTrieSet<T, P, H>
294where
295 T: Eq + Hash + Display,
296 H: Clone,
297 P: SharedPointerKind,
298{
299 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
300 let mut first = true;
301
302 fmt.write_str("{")?;
303
304 for v in self.iter() {
305 if !first {
306 fmt.write_str(", ")?;
307 }
308 v.fmt(fmt)?;
309 first = false;
310 }
311
312 fmt.write_str("}")
313 }
314}
315
316impl<'a, T, P, H: BuildHasher> IntoIterator for &'a HashTrieSet<T, P, H>
317where
318 T: Eq + Hash,
319 H: Default + Clone,
320 P: SharedPointerKind,
321{
322 type Item = &'a T;
323 type IntoIter = Iter<'a, T, P>;
324
325 fn into_iter(self) -> Iter<'a, T, P> {
326 self.iter()
327 }
328}
329
330impl<T, P, H> FromIterator<T> for HashTrieSet<T, P, H>
331where
332 T: Eq + Hash,
333 H: BuildHasher + Clone + Default,
334 P: SharedPointerKind,
335{
336 fn from_iter<I: IntoIterator<Item = T>>(into_iter: I) -> HashTrieSet<T, P, H> {
337 let mut set = HashTrieSet::new_with_hasher_with_ptr_kind(Default::default());
338
339 for v in into_iter {
340 set.insert_mut(v);
341 }
342
343 set
344 }
345}
346
347#[cfg(feature = "serde")]
348pub mod serde {
349 use super::*;
350 use ::serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
351 use ::serde::ser::{Serialize, Serializer};
352 use core::fmt;
353 use core::marker::PhantomData;
354
355 impl<T, P, H> Serialize for HashTrieSet<T, P, H>
356 where
357 T: Eq + Hash + Serialize,
358 H: BuildHasher + Clone + Default,
359 P: SharedPointerKind,
360 {
361 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
362 serializer.collect_seq(self)
363 }
364 }
365
366 impl<'de, T, P, H> Deserialize<'de> for HashTrieSet<T, P, H>
367 where
368 T: Eq + Hash + Deserialize<'de>,
369 H: BuildHasher + Clone + Default,
370 P: SharedPointerKind,
371 {
372 fn deserialize<D: Deserializer<'de>>(
373 deserializer: D,
374 ) -> Result<HashTrieSet<T, P, H>, D::Error> {
375 deserializer.deserialize_seq(HashTrieSetVisitor {
376 _phantom_t: PhantomData,
377 _phantom_h: PhantomData,
378 _phantom_p: PhantomData,
379 })
380 }
381 }
382
383 struct HashTrieSetVisitor<T, P, H> {
384 _phantom_t: PhantomData<T>,
385 _phantom_h: PhantomData<H>,
386 _phantom_p: PhantomData<P>,
387 }
388
389 impl<'de, T, P, H> Visitor<'de> for HashTrieSetVisitor<T, P, H>
390 where
391 T: Eq + Hash + Deserialize<'de>,
392 H: BuildHasher + Clone + Default,
393 P: SharedPointerKind,
394 {
395 type Value = HashTrieSet<T, P, H>;
396
397 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
398 formatter.write_str("a sequence")
399 }
400
401 fn visit_seq<A>(self, mut seq: A) -> Result<HashTrieSet<T, P, H>, A::Error>
402 where
403 A: SeqAccess<'de>,
404 {
405 let mut set = HashTrieSet::new_with_hasher_with_ptr_kind(Default::default());
406
407 while let Some(value) = seq.next_element()? {
408 set.insert_mut(value);
409 }
410
411 Ok(set)
412 }
413 }
414}
415
416#[cfg(test)]
417mod test;