1use crate::SmallMap;
11use std::borrow::Borrow;
12use std::collections::{BTreeSet, HashSet};
13use std::fmt::{self, Debug};
14use std::hash::{BuildHasher, Hash};
15use std::iter::FromIterator;
16
17pub trait AnySet<T> {
26 fn contains(&self, value: &T) -> bool;
28
29 fn len(&self) -> usize;
31
32 fn is_empty(&self) -> bool {
34 self.len() == 0
35 }
36}
37impl<T, const N: usize> AnySet<T> for SmallSet<T, N>
39where
40 T: Eq + Hash,
41{
42 fn contains(&self, value: &T) -> bool {
43 SmallSet::contains(self, value)
44 }
45
46 fn len(&self) -> usize {
47 SmallSet::len(&self)
48 }
49}
50
51impl<T, S> AnySet<T> for HashSet<T, S>
53where
54 T: Eq + Hash,
55 S: BuildHasher,
56{
57 fn contains(&self, value: &T) -> bool {
58 self.contains(value)
59 }
60
61 fn len(&self) -> usize {
62 self.len()
63 }
64}
65
66impl<T> AnySet<T> for BTreeSet<T>
68where
69 T: Ord,
70{
71 fn contains(&self, value: &T) -> bool {
72 self.contains(value)
73 }
74
75 fn len(&self) -> usize {
76 self.len()
77 }
78}
79
80pub struct SmallSet<T, const N: usize> {
94 map: SmallMap<T, (), N>,
95}
96
97impl<T, const N: usize> SmallSet<T, N>
98where
99 T: Eq + Hash,
100{
101 pub fn new() -> Self {
105 Self {
106 map: SmallMap::new(),
107 }
108 }
109
110 #[inline]
112 pub fn is_on_stack(&self) -> bool {
113 self.map.is_on_stack()
114 }
115
116 #[inline]
118 pub fn len(&self) -> usize {
119 self.map.len()
120 }
121
122 #[inline]
124 pub fn is_empty(&self) -> bool {
125 self.map.is_empty()
126 }
127
128 #[inline]
132 pub fn clear(&mut self) {
133 self.map.clear();
134 }
135
136 pub fn insert(&mut self, value: T) -> bool {
143 if self.map.contains_key(&value) {
144 false
145 } else {
146 self.map.insert(value, ());
147 true
148 }
149 }
150
151 pub fn contains<Q>(&self, value: &Q) -> bool
155 where
156 T: Borrow<Q>,
157 Q: Hash + Eq + ?Sized,
158 {
159 self.map.contains_key(value)
160 }
161
162 pub fn remove<Q>(&mut self, value: &Q) -> bool
164 where
165 T: Borrow<Q>,
166 Q: Hash + Eq + ?Sized,
167 {
168 self.map.remove(value).is_some()
169 }
170
171 pub fn retain<F>(&mut self, mut f: F)
176 where
177 F: FnMut(&T) -> bool,
178 {
179 let old_map = std::mem::replace(&mut self.map, SmallMap::new());
183 for (k, _) in old_map {
184 if f(&k) {
185 self.map.insert(k, ());
186 }
187 }
188 }
189
190 pub fn iter(&self) -> SetRefIter<'_, T> {
194 SetRefIter {
195 iter: self.map.iter(),
196 }
197 }
198
199 pub fn difference<'a, S>(&'a self, other: &'a S) -> impl Iterator<Item = &'a T>
203 where
204 S: AnySet<T>,
205 {
206 self.iter().filter(move |v| !other.contains(v))
207 }
208
209 pub fn intersection<'a, S>(&'a self, other: &'a S) -> impl Iterator<Item = &'a T>
211 where
212 S: AnySet<T>,
213 {
214 self.iter().filter(move |v| other.contains(v))
215 }
216
217 pub fn union<'a, I>(&'a self, other: I) -> impl Iterator<Item = &'a T>
221 where
222 I: IntoIterator<Item = &'a T>,
223 I::IntoIter: 'a,
224 {
225 self.iter()
227 .chain(other.into_iter().filter(move |v| !self.contains(v)))
228 }
229
230 pub fn is_disjoint<S>(&self, other: &S) -> bool
232 where
233 S: AnySet<T>,
234 {
235 self.iter().all(|v| !other.contains(v))
236 }
237
238 pub fn is_subset<S>(&self, other: &S) -> bool
242 where
243 S: AnySet<T>,
244 {
245 self.iter().all(|v| other.contains(v))
246 }
247
248 pub fn is_superset<'a, I>(&self, other: I) -> bool
252 where
253 T: 'a,
254 I: IntoIterator<Item = &'a T>,
255 {
256 other.into_iter().all(|v| self.contains(v))
257 }
258
259 pub fn symmetric_difference<'a>(
262 &'a self,
263 other: &'a SmallSet<T, N>,
264 ) -> impl Iterator<Item = &'a T> {
265 self.difference(other).chain(other.difference(self))
267 }
268}
269
270impl<T, const N: usize> Clone for SmallSet<T, N>
275where
276 T: Eq + Hash + Clone,
277{
278 fn clone(&self) -> Self {
279 Self {
280 map: self.map.clone(),
281 }
282 }
283}
284
285impl<T: Eq + Hash, const N: usize> Default for SmallSet<T, N> {
286 fn default() -> Self {
287 Self::new()
288 }
289}
290
291impl<T: Debug + Eq + Hash, const N: usize> Debug for SmallSet<T, N> {
292 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
293 f.debug_set().entries(self.iter()).finish()
294 }
295}
296
297impl<T: Eq + Hash, const N: usize> FromIterator<T> for SmallSet<T, N> {
299 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
300 let mut set = SmallSet::new();
301 for val in iter {
302 set.insert(val);
303 }
304 set
305 }
306}
307
308impl<T: Eq + Hash, const N: usize> IntoIterator for SmallSet<T, N> {
310 type Item = T;
311 type IntoIter = SmallSetIntoIter<T, N>;
312
313 fn into_iter(self) -> Self::IntoIter {
314 SmallSetIntoIter {
315 iter: self.map.into_iter(),
316 }
317 }
318}
319
320pub struct SmallSetIntoIter<T, const N: usize> {
322 iter: crate::SmallMapIntoIter<T, (), N>,
324}
325
326impl<T, const N: usize> Iterator for SmallSetIntoIter<T, N> {
327 type Item = T;
328 fn next(&mut self) -> Option<Self::Item> {
329 self.iter.next().map(|(k, _)| k)
331 }
332}
333
334impl<T, const N: usize> Extend<T> for SmallSet<T, N>
335where
336 T: Eq + Hash + Clone,
337{
338 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
339 for item in iter {
340 self.insert(item);
341 }
342 }
343}
344
345impl<'a, T, const N: usize> Extend<&'a T> for SmallSet<T, N>
347where
348 T: 'a + Eq + Hash + Clone + Copy,
349{
350 fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
351 for item in iter {
352 self.insert(*item);
353 }
354 }
355}
356
357impl<T, const N: usize, S> PartialEq<S> for SmallSet<T, N>
364where
365 T: Eq + Hash + Clone,
366 S: AnySet<T>, {
368 fn eq(&self, other: &S) -> bool {
369 if self.len() != other.len() {
371 return false;
372 }
373
374 self.is_subset(other)
377 }
378}
379
380impl<T, const N: usize> Eq for SmallSet<T, N> where T: Eq + Hash + Clone {}
382
383pub struct SetRefIter<'a, T> {
389 iter: crate::SmallMapIter<'a, T, ()>,
391}
392
393impl<'a, T: 'a> Iterator for SetRefIter<'a, T> {
394 type Item = &'a T;
395
396 fn next(&mut self) -> Option<Self::Item> {
397 self.iter.next().map(|(k, _)| k)
399 }
400}
401
402impl<'a, T, const N: usize> IntoIterator for &'a SmallSet<T, N>
404where
405 T: Eq + Hash,
406{
407 type Item = &'a T;
408 type IntoIter = SetRefIter<'a, T>;
409
410 fn into_iter(self) -> Self::IntoIter {
411 self.iter()
412 }
413}
414
415#[cfg(test)]
420mod tests {
421 use super::*;
422 use std::collections::{BTreeSet, HashSet};
423
424 #[test]
426 fn test_set_stack_ops_basic() {
427 let mut set: SmallSet<i32, 4> = SmallSet::new();
428
429 assert!(set.is_empty());
430 assert_eq!(set.len(), 0);
431 assert!(set.is_on_stack());
432
433 assert!(set.insert(10));
435 assert!(set.insert(20));
436 assert_eq!(set.len(), 2);
437
438 assert!(set.contains(&10));
440 assert!(!set.contains(&99));
441
442 assert!(set.remove(&10));
444 assert!(!set.contains(&10));
445 assert_eq!(set.len(), 1);
446
447 set.clear();
449 assert!(set.is_empty());
450 assert!(set.is_on_stack()); }
452
453 #[test]
454 fn test_set_stack_duplicate_insertion() {
455 let mut set: SmallSet<String, 4> = SmallSet::new();
456
457 assert!(set.insert("A".to_string()));
458 assert_eq!(set.len(), 1);
459
460 assert!(!set.insert("A".to_string()));
462 assert_eq!(set.len(), 1); }
464
465 #[test]
467 fn test_set_spill_trigger_on_insert() {
468 let mut set: SmallSet<i32, 2> = SmallSet::new();
470
471 set.insert(1);
472 set.insert(2);
473 assert!(set.is_on_stack());
474
475 set.insert(3);
477
478 assert!(!set.is_on_stack());
479 assert_eq!(set.len(), 3);
480 assert!(set.contains(&1));
481 assert!(set.contains(&2));
482 assert!(set.contains(&3));
483 }
484
485 #[test]
486 fn test_set_any_storage_growth_on_heap() {
487 let mut set: SmallSet<i32, 2> = SmallSet::new();
488
489 for i in 0..100 {
491 set.insert(i);
492 }
493
494 assert!(!set.is_on_stack());
495 assert_eq!(set.len(), 100);
496 assert!(set.contains(&50));
497 }
498
499 #[test]
501 fn test_set_traits_iter() {
502 let set: SmallSet<i32, 4> = vec![1, 2, 3].into_iter().collect();
503 let collected: Vec<_> = set.iter().cloned().collect(); assert_eq!(collected.len(), 3);
506 assert!(collected.contains(&1));
507 assert!(collected.contains(&2));
508 assert!(collected.contains(&3));
509 }
510
511 #[test]
512 fn test_set_stack_into_iter() {
513 let mut set: SmallSet<i32, 4> = SmallSet::new();
514 set.insert(1);
515 set.insert(2);
516
517 let vec: Vec<i32> = set.into_iter().collect();
519 assert_eq!(vec.len(), 2);
520 assert!(vec.contains(&1));
521 assert!(vec.contains(&2));
522 }
523
524 #[test]
525 fn test_set_any_storage_into_iter_heap() {
526 let mut set: SmallSet<i32, 2> = SmallSet::new();
527 set.insert(1);
528 set.insert(2);
529 set.insert(3); let vec: Vec<i32> = set.into_iter().collect();
533 assert_eq!(vec.len(), 3);
534 assert!(vec.contains(&1));
535 }
536
537 #[test]
539 fn test_set_any_set_difference() {
540 let a: SmallSet<i32, 4> = vec![1, 2, 3].into_iter().collect();
541 let b: SmallSet<i32, 4> = vec![3, 4, 5].into_iter().collect();
542
543 let diff: Vec<_> = a.difference(&b).cloned().collect();
545 assert_eq!(diff.len(), 2);
546 assert!(diff.contains(&1));
547 assert!(diff.contains(&2));
548 assert!(!diff.contains(&3));
549 }
550
551 #[test]
552 fn test_set_any_set_intersection() {
553 let a: SmallSet<i32, 4> = vec![1, 2, 3].into_iter().collect();
554 let b: SmallSet<i32, 4> = vec![2, 3, 4].into_iter().collect();
555
556 let int: Vec<_> = a.intersection(&b).cloned().collect();
558 assert_eq!(int.len(), 2);
559 assert!(int.contains(&2));
560 assert!(int.contains(&3));
561 assert!(!int.contains(&1));
562 }
563
564 #[test]
565 fn test_set_any_set_union() {
566 let a: SmallSet<i32, 4> = vec![1, 2].into_iter().collect();
567 let b: SmallSet<i32, 4> = vec![2, 3].into_iter().collect();
568
569 let u: Vec<_> = a.union(&b).cloned().collect();
572 assert_eq!(u.len(), 3);
573 assert!(u.contains(&1));
574 assert!(u.contains(&2));
575 assert!(u.contains(&3));
576 }
577
578 #[test]
580 fn test_set_any_set_disjoint() {
581 let a: SmallSet<i32, 4> = vec![1, 2].into_iter().collect();
582 let b: SmallSet<i32, 4> = vec![3, 4].into_iter().collect();
583 let c: SmallSet<i32, 4> = vec![2, 3].into_iter().collect();
584
585 assert!(a.is_disjoint(&b)); assert!(!a.is_disjoint(&c)); }
588
589 #[test]
590 fn test_set_any_set_subset() {
591 let sub: SmallSet<i32, 4> = vec![1, 2].into_iter().collect();
592 let sup: SmallSet<i32, 4> = vec![1, 2, 3].into_iter().collect();
593
594 assert!(sub.is_subset(&sup));
595 assert!(!sup.is_subset(&sub));
596
597 let empty: SmallSet<i32, 4> = SmallSet::new();
599 assert!(empty.is_subset(&sub));
600 }
601
602 #[test]
603 fn test_set_any_set_superset() {
604 let sup: SmallSet<i32, 4> = vec![1, 2, 3].into_iter().collect();
605 let sub_vec = vec![1, 2];
606
607 assert!(sup.is_superset(&sub_vec)); assert!(!sup.is_superset(&vec![1, 99])); }
610
611 #[test]
613 fn test_set_traits_interop_hashset() {
614 let small: SmallSet<i32, 4> = vec![1, 2].into_iter().collect();
615 let std_set: HashSet<i32> = vec![1, 2, 3].into_iter().collect();
616
617 assert!(small.is_subset(&std_set));
618
619 let diff: Vec<_> = small.difference(&std_set).collect();
621 assert!(diff.is_empty());
622 }
623
624 #[test]
625 fn test_set_traits_interop_btreeset() {
626 let small: SmallSet<i32, 4> = vec![1, 2].into_iter().collect();
627 let btree: BTreeSet<i32> = vec![2, 3].into_iter().collect();
628
629 let int: Vec<_> = small.intersection(&btree).cloned().collect();
631 assert_eq!(int, vec![2]);
632 }
633
634 #[test]
636 fn test_set_any_storage_retain() {
637 let mut set: SmallSet<i32, 4> = vec![1, 2, 3, 4, 5].into_iter().collect();
638 assert!(!set.is_on_stack());
640
641 set.retain(|x| x % 2 == 0);
643
644 assert_eq!(set.len(), 2);
645 assert!(set.contains(&2));
646 assert!(set.contains(&4));
647 assert!(!set.contains(&1));
648 }
649
650 #[test]
651 fn test_set_any_set_symmetric_difference() {
652 let a: SmallSet<i32, 4> = vec![1, 2, 3].into_iter().collect();
653 let b: SmallSet<i32, 4> = vec![3, 4, 5].into_iter().collect();
654
655 let sym: Vec<_> = a.symmetric_difference(&b).cloned().collect();
657 assert_eq!(sym.len(), 4);
658 assert!(sym.contains(&1));
659 assert!(sym.contains(&4));
660 assert!(!sym.contains(&3)); }
662
663 #[test]
664 fn test_set_traits_equality() {
665 let a: SmallSet<i32, 4> = vec![1, 2, 3].into_iter().collect();
666 let b: SmallSet<i32, 4> = vec![3, 2, 1].into_iter().collect(); let c: SmallSet<i32, 2> = vec![1, 2].into_iter().collect();
668
669 assert_eq!(a, b); assert_ne!(a, c);
671 }
672
673 #[test]
674 fn test_set_traits_extend() {
675 let mut set: SmallSet<i32, 4> = SmallSet::new();
676 set.insert(1);
677
678 let more = vec![2, 3, 4, 5]; set.extend(more);
680
681 assert_eq!(set.len(), 5);
682 assert!(!set.is_on_stack());
683 assert!(set.contains(&5));
684 }
685
686 #[test]
687 fn test_set_traits_clone() {
688 let mut a: SmallSet<i32, 4> = SmallSet::new();
689 a.insert(1);
690
691 let mut b = a.clone();
692 b.insert(2);
693
694 assert!(a.contains(&1));
695 assert!(!a.contains(&2)); assert!(b.contains(&1));
697 assert!(b.contains(&2));
698 }
699
700 #[test]
701 fn test_set_any_storage_clone_heap() {
702 let mut original: SmallSet<String, 4> = SmallSet::new();
703 original.insert("A".to_string());
704 original.insert("B".to_string());
705
706 let mut copy = original.clone();
708
709 copy.insert("C".to_string());
711 copy.remove("A");
712
713 assert!(original.contains("A"));
715 assert!(!original.contains("C"));
716 assert_eq!(original.len(), 2);
717
718 assert!(!copy.contains("A"));
720 assert!(copy.contains("C"));
721 assert_eq!(copy.len(), 2);
722 }
723
724 #[test]
725 fn test_set_traits_equality_different_capacities() {
726 let mut s1: SmallSet<i32, 4> = SmallSet::new();
727 let mut s2: SmallSet<i32, 8> = SmallSet::new();
728
729 s1.insert(1);
730 s1.insert(2);
731
732 s2.insert(2);
733 s2.insert(1);
734
735 assert_eq!(s1, s2);
737
738 s2.insert(3);
740 assert_ne!(s1, s2);
741 }
742
743 #[test]
744 fn test_set_traits_equality_interop() {
745 let mut small: SmallSet<i32, 4> = SmallSet::new();
746 small.insert(1);
747 small.insert(2);
748
749 let mut hash_set = HashSet::new();
751 hash_set.insert(1);
752 hash_set.insert(2);
753
754 assert_eq!(small, hash_set); hash_set.insert(3);
757 assert_ne!(small, hash_set); let mut btree_set = BTreeSet::new();
761 btree_set.insert(1);
762 btree_set.insert(2);
763
764 assert_eq!(small, btree_set); }
766
767 #[test]
768 fn test_set_any_storage_heap_remove() {
769 let mut set: SmallSet<i32, 2> = vec![1, 2, 3].into_iter().collect();
770 assert!(!set.is_on_stack());
771 assert!(set.remove(&2));
772 assert_eq!(set.len(), 2);
773 }
774
775 #[test]
776 fn test_set_any_storage_clone_heap_v2() {
777 let set: SmallSet<i32, 2> = vec![1, 2, 3].into_iter().collect();
778 let cloned = set.clone();
779 assert_eq!(cloned.len(), 3);
780 assert!(!cloned.is_on_stack());
781 }
782
783 #[test]
784 fn test_set_traits_debug_display() {
785 let set: SmallSet<i32, 2> = vec![1].into_iter().collect();
786 let debug = format!("{:?}", set);
787 assert!(debug.contains("1"));
788 }
789
790 #[test]
791 fn test_set_traits_any_set_impl() {
792 let set: SmallSet<i32, 2> = vec![1, 2].into_iter().collect();
793 let any: &dyn AnySet<i32> = &set;
794 assert_eq!(any.len(), 2);
795 assert!(any.contains(&1));
796 assert!(!any.is_empty());
797 }
798
799 #[test]
800 fn test_set_coverage_gaps() {
801 let set: SmallSet<i32, 4> = Default::default();
803 assert!(set.is_empty());
804
805 let mut set: SmallSet<i32, 4> = SmallSet::new();
807 let refs = vec![1, 2, 3];
808 set.extend(&refs);
809 assert_eq!(set.len(), 3);
810 assert!(set.contains(&2));
811 }
812}