1use core::fmt;
2use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Index};
3#[cfg(feature = "serde")]
4use {
5 sequential_storage::map::PostcardValue,
6 serde::{Deserialize, Serialize},
7};
8
9#[derive(Clone, Copy, Debug, Ord, PartialOrd, Eq, PartialEq)]
11#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12pub struct BitSet128(u64, u64);
13
14impl BitSet128 {
15 #[must_use]
17 pub const fn new() -> Self {
18 Self(0, 0)
19 }
20}
21
22#[cfg(feature = "serde")]
23impl PostcardValue<'_> for BitSet128 {}
24
25impl Default for BitSet128 {
26 fn default() -> Self {
27 Self::new()
28 }
29}
30
31impl BitSet128 {
32 #[inline]
34 pub fn reset_all(&mut self) {
35 self.0 = 0;
36 self.1 = 0;
37 }
38
39 #[inline]
41 pub fn reset(&mut self, index: u8) {
42 if index < 64 {
43 self.0 &= !(1u64 << index);
44 } else if index < 128 {
45 self.1 &= !(1u64 << (index - 64));
46 }
47 }
48
49 #[inline]
51 pub fn set_all(&mut self) {
52 self.0 = u64::MAX;
53 self.1 = u64::MAX;
54 }
55
56 #[inline]
58 pub fn set(&mut self, index: u8) {
59 if index < 64 {
60 self.0 |= 1u64 << index;
61 } else if index < 128 {
62 self.1 |= 1u64 << (index - 64);
63 }
64 }
65
66 #[inline]
68 pub fn flip(&mut self, index: u8) {
69 if index < 64 {
70 self.0 ^= 1u64 << index;
71 } else if index < 128 {
72 self.1 ^= 1u64 << (index - 64);
73 }
74 }
75
76 #[inline]
78 pub fn flip_all(&mut self) {
79 self.0 = !self.0;
80 self.1 = !self.1;
81 }
82
83 #[inline]
86 pub fn and_not(&mut self, other: Self) {
87 self.0 &= !other.0;
88 self.1 &= !other.1;
89 }
90
91 #[inline]
94 #[must_use]
95 pub fn test(&self, index: u8) -> bool {
96 if index < 64 {
97 (self.0 & (1u64 << index)) != 0
98 } else if index < 128 {
99 (self.1 & (1u64 << (index - 64))) != 0
100 } else {
101 false
102 }
103 }
104
105 #[allow(clippy::cast_possible_truncation)]
107 #[inline]
108 #[must_use]
109 pub fn bits_0_31(&self) -> u32 {
110 self.0 as u32
111 }
112
113 #[inline]
115 #[must_use]
116 pub fn bits_32_63(&self) -> u32 {
117 (self.0 >> 32) as u32
118 }
119
120 #[allow(clippy::cast_possible_truncation)]
122 #[inline]
123 #[must_use]
124 pub fn bits_64_95(&self) -> u32 {
125 self.1 as u32
126 }
127
128 #[inline]
130 #[must_use]
131 pub fn bits_96_127(&self) -> u32 {
132 (self.1 >> 32) as u32
133 }
134
135 #[inline]
137 #[must_use]
138 pub fn bits_0_63(&self) -> u64 {
139 self.0
140 }
141
142 #[inline]
144 #[must_use]
145 pub fn bits_64_127(&self) -> u64 {
146 self.1
147 }
148
149 #[inline]
151 #[must_use]
152 pub const fn count_ones(&self) -> u32 {
153 self.0.count_ones() + self.1.count_ones()
154 }
155
156 #[inline]
159 #[must_use]
160 pub const fn leading_zeros(&self) -> u32 {
161 if self.1 == 0 {
164 64 + self.0.leading_zeros()
165 } else {
166 self.1.leading_zeros()
169 }
170 }
171
172 #[inline]
174 #[must_use]
175 pub const fn is_empty(&self) -> bool {
176 self.0 == 0 && self.1 == 0
177 }
178 #[inline]
181 #[must_use]
182 pub const fn last_set(&self) -> Option<u8> {
183 let leading = self.leading_zeros();
184 if leading == 128 {
185 None
186 } else {
187 #[allow(clippy::cast_possible_truncation)]
191 Some((127 - leading) as u8)
192 }
193 }
194
195 #[inline]
197 #[must_use]
198 pub const fn is_superset(&self, other: Self) -> bool {
199 (self.0 & other.0) == other.0 && (self.1 & other.1) == other.1
202 }
203
204 #[inline]
206 #[must_use]
207 pub const fn is_subset(&self, other: BitSet128) -> bool {
208 other.is_superset(*self)
209 }
210
211 #[inline]
214 #[must_use]
215 pub const fn intersects(&self, other: Self) -> bool {
216 (self.0 & other.0) != 0 || (self.1 & other.1) != 0
219 }
220
221 #[inline]
223 #[must_use]
224 pub fn iter(&self) -> BitSet128Iter {
225 self.into_iter()
226 }
227}
228
229impl BitOr for BitSet128 {
232 type Output = Self;
233 fn bitor(self, other: Self) -> Self::Output {
234 Self(self.0 | other.0, self.1 | other.1)
235 }
236}
237
238impl BitAnd for BitSet128 {
239 type Output = Self;
240 fn bitand(self, other: Self) -> Self::Output {
241 Self(self.0 & other.0, self.1 & other.1)
242 }
243}
244
245impl BitXor for BitSet128 {
246 type Output = Self;
247 fn bitxor(self, other: Self) -> Self::Output {
248 Self(self.0 ^ other.0, self.1 ^ other.1)
249 }
250}
251
252impl BitOrAssign for BitSet128 {
253 fn bitor_assign(&mut self, other: Self) {
254 self.0 |= other.0;
255 self.1 |= other.1;
256 }
257}
258
259impl BitAndAssign for BitSet128 {
260 fn bitand_assign(&mut self, other: Self) {
261 self.0 &= other.0;
262 self.1 &= other.1;
263 }
264}
265
266impl BitXorAssign for BitSet128 {
267 fn bitxor_assign(&mut self, other: Self) {
268 self.0 ^= other.0;
269 self.1 ^= other.1;
270 }
271}
272
273impl Index<u8> for BitSet128 {
274 type Output = bool;
275
276 fn index(&self, index: u8) -> &Self::Output {
277 if self.test(index) { &true } else { &false }
279 }
280}
281
282impl Index<usize> for BitSet128 {
283 type Output = bool;
284
285 #[allow(clippy::cast_possible_truncation)]
286 fn index(&self, index: usize) -> &Self::Output {
287 if self.test(index as u8) { &true } else { &false }
289 }
290}
291
292impl From<u32> for BitSet128 {
294 #[inline]
295 fn from(a: u32) -> Self {
296 Self(u64::from(a), 0)
297 }
298}
299
300impl From<(u32, u32)> for BitSet128 {
302 #[inline]
303 fn from((a, b): (u32, u32)) -> Self {
304 Self(u64::from(a) << 32 | u64::from(b), 0)
305 }
306}
307
308impl From<(u32, u32, u32, u32)> for BitSet128 {
310 #[inline]
311 fn from((a, b, c, d): (u32, u32, u32, u32)) -> Self {
312 Self(u64::from(a) << 32 | u64::from(b), u64::from(c) << 32 | u64::from(d))
313 }
314}
315
316impl From<u64> for BitSet128 {
318 #[inline]
319 fn from(a: u64) -> Self {
320 Self(a, 0)
321 }
322}
323
324impl From<(u64, u64)> for BitSet128 {
326 #[inline]
327 fn from((a, b): (u64, u64)) -> Self {
328 Self(a, b)
329 }
330}
331
332#[derive(Debug, Default, Eq, PartialEq)]
336pub struct BitSet128Iter(u64, u64);
337
338impl Iterator for BitSet128Iter {
340 type Item = u8;
341
342 fn next(&mut self) -> Option<Self::Item> {
343 if self.0 == 0 {
344 if self.1 == 0 {
345 None
346 } else {
347 #[allow(clippy::cast_possible_truncation)]
349 let index = self.1.trailing_zeros() as u8;
350 self.1 &= self.1 - 1;
352 Some(index + 64)
353 }
354 } else {
355 #[allow(clippy::cast_possible_truncation)]
357 let index = self.0.trailing_zeros() as u8;
358 self.0 &= self.0 - 1;
360 Some(index)
361 }
362 }
363
364 #[inline]
365 fn size_hint(&self) -> (usize, Option<usize>) {
366 let len = (self.0.count_ones() + self.1.count_ones()) as usize;
368 (len, Some(len))
369 }
370}
371
372impl ExactSizeIterator for BitSet128Iter {}
374impl core::iter::FusedIterator for BitSet128Iter {}
375
376impl IntoIterator for &BitSet128 {
378 type Item = u8;
379 type IntoIter = BitSet128Iter;
380
381 fn into_iter(self) -> Self::IntoIter {
382 BitSet128Iter(self.0, self.1)
385 }
386}
387
388impl IntoIterator for BitSet128 {
390 type Item = u8;
391 type IntoIter = BitSet128Iter;
392
393 fn into_iter(self) -> Self::IntoIter {
394 BitSet128Iter(self.0, self.1)
397 }
398}
399
400impl FromIterator<u8> for BitSet128 {
402 fn from_iter<I: IntoIterator<Item = u8>>(iter: I) -> Self {
403 let mut bitset = Self::new();
404 for index in iter {
405 bitset.set(index);
406 }
407 bitset
408 }
409}
410
411impl Extend<u8> for BitSet128 {
412 fn extend<I: IntoIterator<Item = u8>>(&mut self, iter: I) {
413 for index in iter {
414 self.set(index);
415 }
416 }
417}
418
419impl fmt::Binary for BitSet128 {
422 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
423 if f.alternate() {
425 f.write_str("0b")?;
426 }
427 for i in (0..64).rev() {
430 let val = (self.1 >> i) & 1;
431 write!(f, "{val}")?;
432 }
433 for i in (0..64).rev() {
435 let val = (self.0 >> i) & 1;
436 write!(f, "{val}")?;
437 }
438
439 Ok(())
440 }
441}
442
443impl fmt::UpperHex for BitSet128 {
444 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
445 if f.alternate() {
446 f.write_str("0x")?;
447 }
448 write!(f, "{:016X}{:016X}", self.1, self.0)
449 }
450}
451
452#[cfg(test)]
453mod tests {
454 use super::*;
455
456 fn is_normal<T: Sized + Send + Sync + Unpin>() {}
457 fn is_full<T: Sized + Send + Sync + Unpin + Copy + Clone + Default + PartialEq>() {}
458 #[cfg(feature = "serde")]
459 fn is_config<T: Serialize + for<'a> Deserialize<'a>>() {}
460
461 #[test]
462 fn normal_types() {
463 is_full::<BitSet128>();
464 #[cfg(feature = "serde")]
465 is_config::<BitSet128>();
466 is_normal::<BitSet128Iter>();
467 }
468
469 #[test]
470 fn new() {
471 let mut bits = BitSet128::new();
472 bits.set(42);
473 assert!(bits[42u8]);
474 assert!(bits.test(42));
475 }
476
477 #[test]
478 fn const_new() {
479 const FLAGS: BitSet128 = BitSet128::new();
480 const EMPTY_CHECK: bool = FLAGS.is_empty(); assert_eq!(0, FLAGS.0);
482 #[allow(clippy::assertions_on_constants)]
483 {
484 assert!(EMPTY_CHECK);
485 }
486 }
487
488 #[test]
489 fn assign() {
490 let mut bits = BitSet128::new();
491 bits.set(42);
492 assert!(bits[42u8]);
493 assert!(bits.test(42));
494 let mask = bits;
495 assert!(mask.test(42));
496 }
497
498 #[test]
499 fn from() {
500 let _bits = BitSet128::from((0xab_u32, 0x12_u32));
501 }
502
503 #[test]
504 fn flip_all() {
505 let mut bitset = BitSet128::new();
506
507 bitset.set(0);
509 bitset.set(64);
510
511 bitset.flip_all();
512
513 assert!(!bitset.test(0));
515 assert!(!bitset.test(64));
516 assert!(bitset.test(1));
517 assert!(bitset.test(65));
518
519 let mut empty_set = BitSet128::new();
521 empty_set.flip_all(); let mut full_set = BitSet128::new();
524 full_set.set_all();
525
526 assert_eq!(empty_set, full_set);
527
528 empty_set.flip_all(); assert!(empty_set.is_empty());
530 }
531
532 #[test]
533 fn leading_zeros() {
534 let mut bitset = BitSet128::new();
535
536 assert_eq!(bitset.leading_zeros(), 128);
538
539 bitset.set(127);
541 assert_eq!(bitset.leading_zeros(), 0);
542
543 bitset.reset_all();
545 bitset.set(126);
546 assert_eq!(bitset.leading_zeros(), 1);
547
548 bitset.reset_all();
550 bitset.set(64);
551 assert_eq!(bitset.leading_zeros(), 63);
552
553 bitset.reset_all();
555 bitset.set(63);
556 assert_eq!(bitset.leading_zeros(), 64);
557
558 bitset.reset_all();
560 bitset.set(0);
561 assert_eq!(bitset.leading_zeros(), 127);
562 }
563
564 #[test]
565 fn last_set() {
566 let mut bitset = BitSet128::new();
567
568 assert_eq!(bitset.last_set(), None);
570
571 bitset.set(0);
573 assert_eq!(bitset.last_set(), Some(0));
574
575 bitset.set(10);
577 bitset.set(45);
578 assert_eq!(bitset.last_set(), Some(45));
579
580 bitset.reset_all();
582 bitset.set(63);
583 assert_eq!(bitset.last_set(), Some(63));
584
585 bitset.set(64);
587 assert_eq!(bitset.last_set(), Some(64));
588
589 bitset.set(100);
591 bitset.set(127);
592 assert_eq!(bitset.last_set(), Some(127));
593 }
594
595 #[test]
596 fn is_superset() {
597 let mut set_a = BitSet128::new();
598 let mut set_b = BitSet128::new();
599
600 assert!(set_a.is_superset(set_b));
602
603 set_a.set(10);
605 set_a.set(80);
606
607 set_b.set(10);
608
609 assert!(set_a.is_superset(set_b));
611 assert!(!set_b.is_superset(set_a));
613
614 set_b.set(80);
616 assert!(set_a.is_superset(set_b));
617
618 let mut set_c = BitSet128::new();
620 let mut set_d = BitSet128::new();
621 set_c.set(15); set_d.set(15);
624 set_d.set(95); assert!(!set_c.is_superset(set_d));
629 }
630
631 #[test]
632 fn intersects() {
633 let mut set_a = BitSet128::new();
634 let mut set_b = BitSet128::new();
635
636 assert!(!set_a.intersects(set_b));
638
639 set_a.set(15);
641 assert!(!set_a.intersects(set_b));
642
643 set_b.set(15);
645 assert!(set_a.intersects(set_b));
646 assert!(set_b.intersects(set_a));
647
648 set_a.reset_all();
650 set_b.reset_all();
651 set_a.set(10); set_b.set(80); assert!(!set_a.intersects(set_b));
654
655 set_a.set(80);
657 assert!(set_a.intersects(set_b));
658 }
659
660 #[test]
661 fn inplace_logical_ops() {
662 let mut set_a = BitSet128::new();
663 let mut set_b = BitSet128::new();
664
665 set_a.set(10);
667 set_a.set(70);
668
669 set_b.set(10);
670 set_b.set(80);
671
672 let mut result = set_a;
674 result &= set_b;
675 assert!(result.test(10));
676 assert!(!result.test(70));
677 assert!(!result.test(80));
678
679 let mut result = set_a;
681 result |= set_b;
682 assert!(result.test(10));
683 assert!(result.test(70));
684 assert!(result.test(80));
685
686 let mut result = set_a;
688 result ^= set_b;
689 assert!(!result.test(10)); assert!(result.test(70));
691 assert!(result.test(80));
692
693 let mut result = set_a;
695 result.and_not(set_b);
696 assert!(!result.test(10)); assert!(result.test(70)); assert!(!result.test(80)); }
700
701 #[test]
702 fn exercise() {
703 let mut system_flags = BitSet128::new();
704 let error_mask = BitSet128::new(); system_flags |= error_mask;
708
709 system_flags ^= error_mask;
711
712 let mut set_a = BitSet128::new();
716 set_a.set(10);
717 set_a.set(20);
718
719 let mut set_b = BitSet128::new();
720 set_b.set(20);
721 set_b.set(30);
722
723 let common = set_a & set_b;
725 assert!(!common.test(10));
726 assert!(common.test(20));
727 assert!(!common.test(30));
728
729 let all = set_a | set_b;
731 assert!(all.test(10));
732 assert!(all.test(20));
733 assert!(all.test(30));
734
735 let diff = set_a ^ set_b;
737 assert!(diff.test(10));
738 assert!(!diff.test(20));
739 assert!(diff.test(30));
740 }
741
742 #[test]
743 fn test_iterator_empty() {
744 let bitset = BitSet128::new();
745 let mut iter = bitset.iter();
746
747 assert_eq!(iter.size_hint(), (0, Some(0)));
748 assert_eq!(iter.next(), None);
749 }
750
751 #[test]
752 fn test_iterator_single_bits() {
753 let mut bitset = BitSet128::new();
755 bitset.set(0);
756 let mut iter = bitset.iter();
757 assert_eq!(iter.next(), Some(0));
758 assert_eq!(iter.next(), None);
759
760 bitset.reset_all();
762 bitset.set(63);
763 let mut iter = bitset.iter();
764 assert_eq!(iter.next(), Some(63));
765 assert_eq!(iter.next(), None);
766
767 bitset.reset_all();
769 bitset.set(64);
770 let mut iter = bitset.iter();
771 assert_eq!(iter.next(), Some(64));
772 assert_eq!(iter.next(), None);
773
774 bitset.reset_all();
776 bitset.set(127);
777 let mut iter = bitset.iter();
778 assert_eq!(iter.next(), Some(127));
779 assert_eq!(iter.next(), None);
780 }
781
782 #[test]
783 fn test_iterator_multiple_scattered_bits() {
784 let mut bitset = BitSet128::new();
785 let expected_indices = [5, 12, 63, 64, 99, 127];
787
788 for &idx in &expected_indices {
789 bitset.set(idx);
790 }
791
792 let mut iter = bitset.iter();
794 assert_eq!(iter.size_hint(), (expected_indices.len(), Some(expected_indices.len())));
795
796 for &expected in &expected_indices {
798 assert_eq!(iter.next(), Some(expected));
799 }
800 assert_eq!(iter.next(), None);
801 }
802
803 #[test]
804 fn test_iterator_size_hint_drainage() {
805 let mut bitset = BitSet128::new();
806 bitset.set(10);
807 bitset.set(90);
808
809 let mut iter = bitset.iter();
810 assert_eq!(iter.size_hint(), (2, Some(2)));
811 assert_eq!(iter.len(), 2); assert_eq!(iter.next(), Some(10));
814 assert_eq!(iter.size_hint(), (1, Some(1)));
815 assert_eq!(iter.len(), 1);
816
817 assert_eq!(iter.next(), Some(90));
818 assert_eq!(iter.size_hint(), (0, Some(0)));
819 assert_eq!(iter.len(), 0);
820
821 assert_eq!(iter.next(), None);
822 }
823
824 #[test]
825 fn test_iterator_all_bits_set() {
826 let mut bitset = BitSet128::new();
827 bitset.set_all();
828
829 let mut count = 0;
830 #[allow(clippy::cast_possible_truncation)]
831 for (expected_idx, actual_idx) in bitset.iter().enumerate() {
832 assert_eq!(expected_idx as u8, actual_idx);
833 count += 1;
834 }
835 assert_eq!(count, 128);
836 }
837
838 #[test]
839 fn test_consuming_into_iter() {
840 let mut bitset = BitSet128::new();
841 bitset.set(42);
842
843 let mut count = 0;
844 for idx in bitset {
845 assert_eq!(idx, 42);
846 count += 1;
847 }
848 assert_eq!(count, 1);
849 }
850
851 #[test]
852 fn from_iterator() {
853 let indices = [5, 63, 64, 120];
855 let bitset: BitSet128 = indices.into_iter().collect();
856
857 assert!(bitset.test(5));
858 assert!(bitset.test(63));
859 assert!(bitset.test(64));
860 assert!(bitset.test(120));
861 assert_eq!(bitset.count_ones(), 4);
862
863 let invalid_indices = [20, 200, 255];
865 let safe_bitset: BitSet128 = invalid_indices.into_iter().collect();
866
867 assert!(safe_bitset.test(20));
868 assert_eq!(safe_bitset.count_ones(), 1); }
870
871 #[test]
872 fn empty_and_full() {
873 let empty = BitSet128::new();
874 assert_eq!(empty.iter().count(), 0);
875
876 let mut full = BitSet128::new();
877 full.set_all();
878 assert_eq!(full.iter().count(), 128);
879 }
880}