1use std::borrow::Borrow;
25use std::collections::hash_map::RandomState;
26use std::collections::{self, BTreeSet};
27use std::fmt::{Debug, Error, Formatter};
28use std::hash::{BuildHasher, Hash};
29use std::iter::{FromIterator, FusedIterator, Sum};
30use std::ops::{Add, Deref, Mul};
31
32use archery::{SharedPointer, SharedPointerKind};
33use equivalent::Equivalent;
34
35use crate::nodes::hamt::{hash_key, Drain as NodeDrain, HashValue, Iter as NodeIter, Node};
36use crate::ordset::GenericOrdSet;
37use crate::shared_ptr::DefaultSharedPtr;
38use crate::GenericVector;
39
40#[macro_export]
55macro_rules! hashset {
56 () => { $crate::hashset::HashSet::new() };
57
58 ( $($x:expr),* ) => {{
59 let mut l = $crate::hashset::HashSet::new();
60 $(
61 l.insert($x);
62 )*
63 l
64 }};
65
66 ( $($x:expr ,)* ) => {{
67 let mut l = $crate::hashset::HashSet::new();
68 $(
69 l.insert($x);
70 )*
71 l
72 }};
73}
74
75pub type HashSet<A> = GenericHashSet<A, RandomState, DefaultSharedPtr>;
81
82pub struct GenericHashSet<A, S, P: SharedPointerKind> {
101 hasher: S,
102 root: Option<SharedPointer<Node<Value<A>, P>, P>>,
103 size: usize,
104}
105
106#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
107struct Value<A>(A);
108
109impl<A> Deref for Value<A> {
110 type Target = A;
111 fn deref(&self) -> &Self::Target {
112 &self.0
113 }
114}
115
116impl<A> HashValue for Value<A>
119where
120 A: Hash + Eq,
121{
122 type Key = A;
123
124 fn extract_key(&self) -> &Self::Key {
125 &self.0
126 }
127
128 fn ptr_eq(&self, _other: &Self) -> bool {
129 false
130 }
131}
132
133impl<A, S, P> GenericHashSet<A, S, P>
134where
135 A: Hash + Eq + Clone,
136 S: BuildHasher + Default + Clone,
137 P: SharedPointerKind,
138{
139 #[inline]
151 #[must_use]
152 pub fn unit(a: A) -> Self {
153 GenericHashSet::new().update(a)
154 }
155}
156
157impl<A, S, P: SharedPointerKind> GenericHashSet<A, S, P> {
158 #[must_use]
160 pub fn new() -> Self
161 where
162 S: Default,
163 {
164 Self::default()
165 }
166
167 #[inline]
184 #[must_use]
185 pub fn is_empty(&self) -> bool {
186 self.len() == 0
187 }
188
189 #[inline]
201 #[must_use]
202 pub fn len(&self) -> usize {
203 self.size
204 }
205
206 pub fn ptr_eq(&self, other: &Self) -> bool {
216 match (&self.root, &other.root) {
217 (Some(a), Some(b)) => SharedPointer::ptr_eq(a, b),
218 (None, None) => true,
219 _ => false,
220 }
221 }
222
223 #[inline]
225 #[must_use]
226 pub fn with_hasher(hasher: S) -> Self {
227 GenericHashSet {
228 size: 0,
229 root: None,
230 hasher,
231 }
232 }
233
234 #[must_use]
238 pub fn hasher(&self) -> &S {
239 &self.hasher
240 }
241
242 #[inline]
244 #[must_use]
245 pub fn new_from<A2>(&self) -> GenericHashSet<A2, S, P>
246 where
247 A2: Hash + Eq + Clone,
248 S: Clone,
249 {
250 GenericHashSet {
251 size: 0,
252 root: None,
253 hasher: self.hasher.clone(),
254 }
255 }
256
257 pub fn clear(&mut self) {
274 self.root = None;
275 self.size = 0;
276 }
277
278 #[must_use]
286 pub fn iter(&self) -> Iter<'_, A, P> {
287 Iter {
288 it: NodeIter::new(self.root.as_deref(), self.size),
289 }
290 }
291}
292
293impl<A, S, P> GenericHashSet<A, S, P>
294where
295 A: Hash + Eq,
296 S: BuildHasher,
297 P: SharedPointerKind,
298{
299 fn test_eq<S2: BuildHasher, P2: SharedPointerKind>(
300 &self,
301 other: &GenericHashSet<A, S2, P2>,
302 ) -> bool {
303 if self.len() != other.len() {
304 return false;
305 }
306 let mut seen = collections::HashSet::new();
307 for value in self.iter() {
308 if !other.contains(value) {
309 return false;
310 }
311 seen.insert(value);
312 }
313 for value in other.iter() {
314 if !seen.contains(&value) {
315 return false;
316 }
317 }
318 true
319 }
320
321 #[must_use]
325 pub fn contains<Q>(&self, value: &Q) -> bool
326 where
327 Q: Hash + Equivalent<A> + ?Sized,
328 {
329 if let Some(root) = &self.root {
330 root.get(hash_key(&self.hasher, value), 0, value).is_some()
331 } else {
332 false
333 }
334 }
335
336 #[must_use]
341 pub fn is_subset<RS>(&self, other: RS) -> bool
342 where
343 RS: Borrow<Self>,
344 {
345 let o = other.borrow();
346 self.iter().all(|a| o.contains(a))
347 }
348
349 #[must_use]
355 pub fn is_proper_subset<RS>(&self, other: RS) -> bool
356 where
357 RS: Borrow<Self>,
358 {
359 self.len() != other.borrow().len() && self.is_subset(other)
360 }
361}
362
363impl<A, S, P> GenericHashSet<A, S, P>
364where
365 A: Hash + Eq + Clone,
366 S: BuildHasher + Clone,
367 P: SharedPointerKind,
368{
369 #[inline]
373 pub fn insert(&mut self, a: A) -> Option<A> {
374 let hash = hash_key(&self.hasher, &a);
375 let root = SharedPointer::make_mut(self.root.get_or_insert_with(Default::default));
376 match root.insert(hash, 0, Value(a)) {
377 None => {
378 self.size += 1;
379 None
380 }
381 Some(Value(old_value)) => Some(old_value),
382 }
383 }
384
385 pub fn remove<Q>(&mut self, value: &Q) -> Option<A>
389 where
390 Q: Hash + Equivalent<A> + ?Sized,
391 {
392 let root = SharedPointer::make_mut(self.root.get_or_insert_with(Default::default));
393 let result = root.remove(hash_key(&self.hasher, value), 0, value);
394 if result.is_some() {
395 self.size -= 1;
396 }
397 result.map(|v| v.0)
398 }
399
400 #[must_use]
418 pub fn update(&self, a: A) -> Self {
419 let mut out = self.clone();
420 out.insert(a);
421 out
422 }
423
424 #[must_use]
429 pub fn without<Q>(&self, value: &Q) -> Self
430 where
431 Q: Hash + Equivalent<A> + ?Sized,
432 {
433 let mut out = self.clone();
434 out.remove(value);
435 out
436 }
437
438 pub fn retain<F>(&mut self, mut f: F)
458 where
459 F: FnMut(&A) -> bool,
460 {
461 let Some(root) = &mut self.root else {
462 return;
463 };
464 let old_root = root.clone();
465 let root = SharedPointer::make_mut(root);
466 for (value, hash) in NodeIter::new(Some(&old_root), self.size) {
467 if !f(value) && root.remove(hash, 0, &**value).is_some() {
468 self.size -= 1;
469 }
470 }
471 }
472
473 #[must_use]
488 pub fn union(self, other: Self) -> Self {
489 let (mut to_mutate, to_consume) = if self.len() >= other.len() {
490 (self, other)
491 } else {
492 (other, self)
493 };
494 for value in to_consume {
495 to_mutate.insert(value);
496 }
497 to_mutate
498 }
499
500 #[must_use]
504 pub fn unions<I>(i: I) -> Self
505 where
506 I: IntoIterator<Item = Self>,
507 S: Default,
508 {
509 i.into_iter().fold(Self::default(), Self::union)
510 }
511
512 #[deprecated(
532 since = "2.0.1",
533 note = "to avoid conflicting behaviors between std and imbl, the `difference` alias for `symmetric_difference` will be removed."
534 )]
535 #[must_use]
536 pub fn difference(self, other: Self) -> Self {
537 self.symmetric_difference(other)
538 }
539
540 #[must_use]
555 pub fn symmetric_difference(mut self, other: Self) -> Self {
556 for value in other {
557 if self.remove(&value).is_none() {
558 self.insert(value);
559 }
560 }
561 self
562 }
563
564 #[must_use]
580 pub fn relative_complement(mut self, other: Self) -> Self {
581 for value in other {
582 let _ = self.remove(&value);
583 }
584 self
585 }
586
587 #[must_use]
602 pub fn intersection(self, other: Self) -> Self {
603 let mut out = self.new_from();
604 for value in other {
605 if self.contains(&value) {
606 out.insert(value);
607 }
608 }
609 out
610 }
611}
612
613impl<A, S, P: SharedPointerKind> Clone for GenericHashSet<A, S, P>
616where
617 A: Clone,
618 S: Clone,
619 P: SharedPointerKind,
620{
621 #[inline]
625 fn clone(&self) -> Self {
626 GenericHashSet {
627 hasher: self.hasher.clone(),
628 root: self.root.clone(),
629 size: self.size,
630 }
631 }
632}
633
634impl<A, S1, P1, S2, P2> PartialEq<GenericHashSet<A, S2, P2>> for GenericHashSet<A, S1, P1>
635where
636 A: Hash + Eq,
637 S1: BuildHasher,
638 S2: BuildHasher,
639 P1: SharedPointerKind,
640 P2: SharedPointerKind,
641{
642 fn eq(&self, other: &GenericHashSet<A, S2, P2>) -> bool {
643 self.test_eq(other)
644 }
645}
646
647impl<A, S, P> Eq for GenericHashSet<A, S, P>
648where
649 A: Hash + Eq,
650 S: BuildHasher,
651 P: SharedPointerKind,
652{
653}
654
655impl<A, S, P> Default for GenericHashSet<A, S, P>
656where
657 S: Default,
658 P: SharedPointerKind,
659{
660 fn default() -> Self {
661 GenericHashSet {
662 hasher: Default::default(),
663 root: None,
664 size: 0,
665 }
666 }
667}
668
669impl<A, S, P> Add for GenericHashSet<A, S, P>
670where
671 A: Hash + Eq + Clone,
672 S: BuildHasher + Clone,
673 P: SharedPointerKind,
674{
675 type Output = GenericHashSet<A, S, P>;
676
677 fn add(self, other: Self) -> Self::Output {
678 self.union(other)
679 }
680}
681
682impl<A, S, P> Mul for GenericHashSet<A, S, P>
683where
684 A: Hash + Eq + Clone,
685 S: BuildHasher + Clone,
686 P: SharedPointerKind,
687{
688 type Output = GenericHashSet<A, S, P>;
689
690 fn mul(self, other: Self) -> Self::Output {
691 self.intersection(other)
692 }
693}
694
695impl<A, S, P> Add for &GenericHashSet<A, S, P>
696where
697 A: Hash + Eq + Clone,
698 S: BuildHasher + Clone,
699 P: SharedPointerKind,
700{
701 type Output = GenericHashSet<A, S, P>;
702
703 fn add(self, other: Self) -> Self::Output {
704 self.clone().union(other.clone())
705 }
706}
707
708impl<A, S, P> Mul for &GenericHashSet<A, S, P>
709where
710 A: Hash + Eq + Clone,
711 S: BuildHasher + Clone,
712 P: SharedPointerKind,
713{
714 type Output = GenericHashSet<A, S, P>;
715
716 fn mul(self, other: Self) -> Self::Output {
717 self.clone().intersection(other.clone())
718 }
719}
720
721impl<A, S, P: SharedPointerKind> Sum for GenericHashSet<A, S, P>
722where
723 A: Hash + Eq + Clone,
724 S: BuildHasher + Default + Clone,
725 P: SharedPointerKind,
726{
727 fn sum<I>(it: I) -> Self
728 where
729 I: Iterator<Item = Self>,
730 {
731 it.fold(Self::default(), |a, b| a + b)
732 }
733}
734
735impl<A, S, R, P: SharedPointerKind> Extend<R> for GenericHashSet<A, S, P>
736where
737 A: Hash + Eq + Clone + From<R>,
738 S: BuildHasher + Clone,
739{
740 fn extend<I>(&mut self, iter: I)
741 where
742 I: IntoIterator<Item = R>,
743 {
744 for value in iter {
745 self.insert(From::from(value));
746 }
747 }
748}
749
750impl<A, S, P> Debug for GenericHashSet<A, S, P>
751where
752 A: Hash + Eq + Debug,
753 S: BuildHasher,
754 P: SharedPointerKind,
755{
756 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
757 f.debug_set().entries(self.iter()).finish()
758 }
759}
760
761pub struct Iter<'a, A, P: SharedPointerKind> {
765 it: NodeIter<'a, Value<A>, P>,
766}
767
768impl<'a, A, P: SharedPointerKind> Clone for Iter<'a, A, P> {
770 fn clone(&self) -> Self {
771 Iter {
772 it: self.it.clone(),
773 }
774 }
775}
776
777impl<'a, A, P> Iterator for Iter<'a, A, P>
778where
779 A: 'a,
780 P: SharedPointerKind,
781{
782 type Item = &'a A;
783
784 fn next(&mut self) -> Option<Self::Item> {
785 self.it.next().map(|(v, _)| &v.0)
786 }
787
788 fn size_hint(&self) -> (usize, Option<usize>) {
789 self.it.size_hint()
790 }
791}
792
793impl<'a, A, P: SharedPointerKind> ExactSizeIterator for Iter<'a, A, P> {}
794
795impl<'a, A, P: SharedPointerKind> FusedIterator for Iter<'a, A, P> {}
796
797pub struct ConsumingIter<A, P>
799where
800 A: Hash + Eq + Clone,
801 P: SharedPointerKind,
802{
803 it: NodeDrain<Value<A>, P>,
804}
805
806impl<A, P> Iterator for ConsumingIter<A, P>
807where
808 A: Hash + Eq + Clone,
809 P: SharedPointerKind,
810{
811 type Item = A;
812
813 fn next(&mut self) -> Option<Self::Item> {
814 self.it.next().map(|(v, _)| v.0)
815 }
816
817 fn size_hint(&self) -> (usize, Option<usize>) {
818 self.it.size_hint()
819 }
820}
821
822impl<A, P> ExactSizeIterator for ConsumingIter<A, P>
823where
824 A: Hash + Eq + Clone,
825 P: SharedPointerKind,
826{
827}
828
829impl<A, P> FusedIterator for ConsumingIter<A, P>
830where
831 A: Hash + Eq + Clone,
832 P: SharedPointerKind,
833{
834}
835
836impl<A, RA, S, P> FromIterator<RA> for GenericHashSet<A, S, P>
839where
840 A: Hash + Eq + Clone + From<RA>,
841 S: BuildHasher + Default + Clone,
842 P: SharedPointerKind,
843{
844 fn from_iter<T>(i: T) -> Self
845 where
846 T: IntoIterator<Item = RA>,
847 {
848 let mut set = Self::default();
849 for value in i {
850 set.insert(From::from(value));
851 }
852 set
853 }
854}
855
856impl<'a, A, S, P> IntoIterator for &'a GenericHashSet<A, S, P>
857where
858 A: Hash + Eq,
859 S: BuildHasher,
860 P: SharedPointerKind,
861{
862 type Item = &'a A;
863 type IntoIter = Iter<'a, A, P>;
864
865 fn into_iter(self) -> Self::IntoIter {
866 self.iter()
867 }
868}
869
870impl<A, S, P> IntoIterator for GenericHashSet<A, S, P>
871where
872 A: Hash + Eq + Clone,
873 S: BuildHasher,
874 P: SharedPointerKind,
875{
876 type Item = A;
877 type IntoIter = ConsumingIter<Self::Item, P>;
878
879 fn into_iter(self) -> Self::IntoIter {
880 ConsumingIter {
881 it: NodeDrain::new(self.root, self.size),
882 }
883 }
884}
885
886impl<A, OA, SA, SB, P1, P2> From<&GenericHashSet<&A, SA, P1>> for GenericHashSet<OA, SB, P2>
889where
890 A: ToOwned<Owned = OA> + Hash + Equivalent<A> + ?Sized,
891 OA: Hash + Eq + Clone,
892 SA: BuildHasher,
893 SB: BuildHasher + Default + Clone,
894 P1: SharedPointerKind,
895 P2: SharedPointerKind,
896{
897 fn from(set: &GenericHashSet<&A, SA, P1>) -> Self {
898 set.iter().map(|a| (*a).to_owned()).collect()
899 }
900}
901
902impl<A, S, const N: usize, P> From<[A; N]> for GenericHashSet<A, S, P>
903where
904 A: Hash + Eq + Clone,
905 S: BuildHasher + Default + Clone,
906 P: SharedPointerKind,
907{
908 fn from(arr: [A; N]) -> Self {
909 IntoIterator::into_iter(arr).collect()
910 }
911}
912
913impl<'a, A, S, P> From<&'a [A]> for GenericHashSet<A, S, P>
914where
915 A: Hash + Eq + Clone,
916 S: BuildHasher + Default + Clone,
917 P: SharedPointerKind,
918{
919 fn from(slice: &'a [A]) -> Self {
920 slice.iter().cloned().collect()
921 }
922}
923
924impl<A, S, P> From<Vec<A>> for GenericHashSet<A, S, P>
925where
926 A: Hash + Eq + Clone,
927 S: BuildHasher + Default + Clone,
928 P: SharedPointerKind,
929{
930 fn from(vec: Vec<A>) -> Self {
931 vec.into_iter().collect()
932 }
933}
934
935impl<A, S, P> From<&Vec<A>> for GenericHashSet<A, S, P>
936where
937 A: Hash + Eq + Clone,
938 S: BuildHasher + Default + Clone,
939 P: SharedPointerKind,
940{
941 fn from(vec: &Vec<A>) -> Self {
942 vec.iter().cloned().collect()
943 }
944}
945
946impl<A, S, P1, P2> From<GenericVector<A, P2>> for GenericHashSet<A, S, P1>
947where
948 A: Hash + Eq + Clone,
949 S: BuildHasher + Default + Clone,
950 P1: SharedPointerKind,
951 P2: SharedPointerKind,
952{
953 fn from(vector: GenericVector<A, P2>) -> Self {
954 vector.into_iter().collect()
955 }
956}
957
958impl<A, S, P1, P2> From<&GenericVector<A, P2>> for GenericHashSet<A, S, P1>
959where
960 A: Hash + Eq + Clone,
961 S: BuildHasher + Default + Clone,
962 P1: SharedPointerKind,
963 P2: SharedPointerKind,
964{
965 fn from(vector: &GenericVector<A, P2>) -> Self {
966 vector.iter().cloned().collect()
967 }
968}
969
970impl<A, S, P> From<collections::HashSet<A>> for GenericHashSet<A, S, P>
971where
972 A: Eq + Hash + Clone,
973 S: BuildHasher + Default + Clone,
974 P: SharedPointerKind,
975{
976 fn from(hash_set: collections::HashSet<A>) -> Self {
977 hash_set.into_iter().collect()
978 }
979}
980
981impl<A, S, P> From<&collections::HashSet<A>> for GenericHashSet<A, S, P>
982where
983 A: Eq + Hash + Clone,
984 S: BuildHasher + Default + Clone,
985 P: SharedPointerKind,
986{
987 fn from(hash_set: &collections::HashSet<A>) -> Self {
988 hash_set.iter().cloned().collect()
989 }
990}
991
992impl<A, S, P> From<&BTreeSet<A>> for GenericHashSet<A, S, P>
993where
994 A: Hash + Eq + Clone,
995 S: BuildHasher + Default + Clone,
996 P: SharedPointerKind,
997{
998 fn from(btree_set: &BTreeSet<A>) -> Self {
999 btree_set.iter().cloned().collect()
1000 }
1001}
1002
1003impl<A, S, P1, P2> From<GenericOrdSet<A, P2>> for GenericHashSet<A, S, P1>
1004where
1005 A: Ord + Hash + Eq + Clone,
1006 S: BuildHasher + Default + Clone,
1007 P1: SharedPointerKind,
1008 P2: SharedPointerKind,
1009{
1010 fn from(ordset: GenericOrdSet<A, P2>) -> Self {
1011 ordset.into_iter().collect()
1012 }
1013}
1014
1015impl<A, S, P1, P2> From<&GenericOrdSet<A, P2>> for GenericHashSet<A, S, P1>
1016where
1017 A: Ord + Hash + Eq + Clone,
1018 S: BuildHasher + Default + Clone,
1019 P1: SharedPointerKind,
1020 P2: SharedPointerKind,
1021{
1022 fn from(ordset: &GenericOrdSet<A, P2>) -> Self {
1023 ordset.into_iter().cloned().collect()
1024 }
1025}
1026
1027#[cfg(any(test, feature = "proptest"))]
1029#[doc(hidden)]
1030pub mod proptest {
1031 #[deprecated(
1032 since = "14.3.0",
1033 note = "proptest strategies have moved to imbl::proptest"
1034 )]
1035 pub use crate::proptest::hash_set;
1036}
1037
1038#[cfg(test)]
1039mod test {
1040 use super::proptest::*;
1041 use super::*;
1042 use crate::test::LolHasher;
1043 use ::proptest::num::i16;
1044 use ::proptest::proptest;
1045 use static_assertions::{assert_impl_all, assert_not_impl_any};
1046 use std::hash::BuildHasherDefault;
1047
1048 assert_impl_all!(HashSet<i32>: Send, Sync);
1049 assert_not_impl_any!(HashSet<*const i32>: Send, Sync);
1050 assert_covariant!(HashSet<T> in T);
1051
1052 #[test]
1053 fn insert_failing() {
1054 let mut set: GenericHashSet<i16, BuildHasherDefault<LolHasher>, DefaultSharedPtr> =
1055 Default::default();
1056 set.insert(14658);
1057 assert_eq!(1, set.len());
1058 set.insert(-19198);
1059 assert_eq!(2, set.len());
1060 }
1061
1062 #[test]
1063 fn match_strings_with_string_slices() {
1064 let mut set: HashSet<String> = From::from(&hashset!["foo", "bar"]);
1065 set = set.without("bar");
1066 assert!(!set.contains("bar"));
1067 set.remove("foo");
1068 assert!(!set.contains("foo"));
1069 }
1070
1071 #[test]
1072 fn macro_allows_trailing_comma() {
1073 let set1 = hashset! {"foo", "bar"};
1074 let set2 = hashset! {
1075 "foo",
1076 "bar",
1077 };
1078 assert_eq!(set1, set2);
1079 }
1080
1081 #[test]
1082 fn issue_60_drain_iterator_memory_corruption() {
1083 use crate::test::MetroHashBuilder;
1084 for i in 0..1000 {
1085 let mut lhs = vec![0, 1, 2];
1086 lhs.sort_unstable();
1087
1088 let hasher = MetroHashBuilder::new(i);
1089 let mut iset: GenericHashSet<_, MetroHashBuilder, DefaultSharedPtr> =
1090 GenericHashSet::with_hasher(hasher);
1091 for &i in &lhs {
1092 iset.insert(i);
1093 }
1094
1095 let mut rhs: Vec<_> = iset.clone().into_iter().collect();
1096 rhs.sort_unstable();
1097
1098 if lhs != rhs {
1099 println!("iteration: {}", i);
1100 println!("seed: {}", hasher.seed());
1101 println!("lhs: {}: {:?}", lhs.len(), &lhs);
1102 println!("rhs: {}: {:?}", rhs.len(), &rhs);
1103 panic!();
1104 }
1105 }
1106 }
1107
1108 proptest! {
1109 #[test]
1110 fn proptest_a_set(ref s in hash_set(".*", 10..100)) {
1111 assert!(s.len() < 100);
1112 assert!(s.len() >= 10);
1113 }
1114 }
1115}