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 #[inline]
107 #[must_use]
108 pub const fn count_ones(&self) -> u32 {
109 self.0.count_ones() + self.1.count_ones()
110 }
111
112 #[inline]
115 #[must_use]
116 pub const fn leading_zeros(&self) -> u32 {
117 if self.1 == 0 {
120 64 + self.0.leading_zeros()
121 } else {
122 self.1.leading_zeros()
125 }
126 }
127
128 #[inline]
130 #[must_use]
131 pub const fn is_empty(&self) -> bool {
132 self.0 == 0 && self.1 == 0
133 }
134 #[inline]
137 #[must_use]
138 pub const fn last_set(&self) -> Option<u8> {
139 let leading = self.leading_zeros();
140 if leading == 128 {
141 None
142 } else {
143 #[allow(clippy::cast_possible_truncation)]
147 Some((127 - leading) as u8)
148 }
149 }
150
151 #[inline]
153 #[must_use]
154 pub const fn is_superset(&self, other: Self) -> bool {
155 (self.0 & other.0) == other.0 && (self.1 & other.1) == other.1
158 }
159
160 #[inline]
162 #[must_use]
163 pub const fn is_subset(&self, other: BitSet128) -> bool {
164 other.is_superset(*self)
165 }
166
167 #[inline]
170 #[must_use]
171 pub const fn intersects(&self, other: Self) -> bool {
172 (self.0 & other.0) != 0 || (self.1 & other.1) != 0
175 }
176
177 #[inline]
179 #[must_use]
180 pub fn iter(&self) -> BitSet128Iter {
181 self.into_iter()
182 }
183}
184
185impl BitOr for BitSet128 {
188 type Output = Self;
189 fn bitor(self, other: Self) -> Self::Output {
190 Self(self.0 | other.0, self.1 | other.1)
191 }
192}
193
194impl BitAnd for BitSet128 {
195 type Output = Self;
196 fn bitand(self, other: Self) -> Self::Output {
197 Self(self.0 & other.0, self.1 & other.1)
198 }
199}
200
201impl BitXor for BitSet128 {
202 type Output = Self;
203 fn bitxor(self, other: Self) -> Self::Output {
204 Self(self.0 ^ other.0, self.1 ^ other.1)
205 }
206}
207
208impl BitOrAssign for BitSet128 {
209 fn bitor_assign(&mut self, other: Self) {
210 self.0 |= other.0;
211 self.1 |= other.1;
212 }
213}
214
215impl BitAndAssign for BitSet128 {
216 fn bitand_assign(&mut self, other: Self) {
217 self.0 &= other.0;
218 self.1 &= other.1;
219 }
220}
221
222impl BitXorAssign for BitSet128 {
223 fn bitxor_assign(&mut self, other: Self) {
224 self.0 ^= other.0;
225 self.1 ^= other.1;
226 }
227}
228
229impl Index<u8> for BitSet128 {
230 type Output = bool;
231
232 fn index(&self, index: u8) -> &Self::Output {
233 if self.test(index) { &true } else { &false }
235 }
236}
237
238impl Index<usize> for BitSet128 {
239 type Output = bool;
240
241 #[allow(clippy::cast_possible_truncation)]
242 fn index(&self, index: usize) -> &Self::Output {
243 if self.test(index as u8) { &true } else { &false }
245 }
246}
247
248impl From<u32> for BitSet128 {
250 #[inline]
251 fn from(a: u32) -> Self {
252 Self(u64::from(a), 0)
253 }
254}
255
256impl From<(u32, u32)> for BitSet128 {
258 #[inline]
259 fn from((a, b): (u32, u32)) -> Self {
260 Self(u64::from(a) << 32 | u64::from(b), 0)
261 }
262}
263
264impl From<(u32, u32, u32, u32)> for BitSet128 {
266 #[inline]
267 fn from((a, b, c, d): (u32, u32, u32, u32)) -> Self {
268 Self(u64::from(a) << 32 | u64::from(b), u64::from(c) << 32 | u64::from(d))
269 }
270}
271
272#[derive(Debug, Default, Eq, PartialEq)]
276pub struct BitSet128Iter(u64, u64);
277
278impl Iterator for BitSet128Iter {
280 type Item = u8;
281
282 fn next(&mut self) -> Option<Self::Item> {
283 if self.0 == 0 {
284 if self.1 == 0 {
285 None
286 } else {
287 #[allow(clippy::cast_possible_truncation)]
289 let index = self.1.trailing_zeros() as u8;
290 self.1 &= self.1 - 1;
292 Some(index + 64)
293 }
294 } else {
295 #[allow(clippy::cast_possible_truncation)]
297 let index = self.0.trailing_zeros() as u8;
298 self.0 &= self.0 - 1;
300 Some(index)
301 }
302 }
303
304 #[inline]
305 fn size_hint(&self) -> (usize, Option<usize>) {
306 let len = (self.0.count_ones() + self.1.count_ones()) as usize;
308 (len, Some(len))
309 }
310}
311
312impl ExactSizeIterator for BitSet128Iter {}
314impl core::iter::FusedIterator for BitSet128Iter {}
315
316impl IntoIterator for &BitSet128 {
318 type Item = u8;
319 type IntoIter = BitSet128Iter;
320
321 fn into_iter(self) -> Self::IntoIter {
322 BitSet128Iter(self.0, self.1)
325 }
326}
327
328impl IntoIterator for BitSet128 {
330 type Item = u8;
331 type IntoIter = BitSet128Iter;
332
333 fn into_iter(self) -> Self::IntoIter {
334 BitSet128Iter(self.0, self.1)
337 }
338}
339
340impl FromIterator<u8> for BitSet128 {
342 fn from_iter<I: IntoIterator<Item = u8>>(iter: I) -> Self {
343 let mut bitset = Self::new();
344 for index in iter {
345 bitset.set(index);
346 }
347 bitset
348 }
349}
350
351impl Extend<u8> for BitSet128 {
352 fn extend<I: IntoIterator<Item = u8>>(&mut self, iter: I) {
353 for index in iter {
354 self.set(index);
355 }
356 }
357}
358
359impl fmt::Binary for BitSet128 {
362 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
363 if f.alternate() {
365 f.write_str("0b")?;
366 }
367 for i in (0..64).rev() {
370 let val = (self.1 >> i) & 1;
371 write!(f, "{val}")?;
372 }
373 for i in (0..64).rev() {
375 let val = (self.0 >> i) & 1;
376 write!(f, "{val}")?;
377 }
378
379 Ok(())
380 }
381}
382
383impl fmt::UpperHex for BitSet128 {
384 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
385 if f.alternate() {
386 f.write_str("0x")?;
387 }
388 write!(f, "{:016X}{:016X}", self.1, self.0)
389 }
390}
391
392#[cfg(test)]
393mod tests {
394 use super::*;
395
396 fn is_normal<T: Sized + Send + Sync + Unpin>() {}
397 fn is_full<T: Sized + Send + Sync + Unpin + Copy + Clone + Default + PartialEq>() {}
398 #[cfg(feature = "serde")]
399 fn is_config<T: Serialize + for<'a> Deserialize<'a>>() {}
400
401 #[test]
402 fn normal_types() {
403 is_full::<BitSet128>();
404 #[cfg(feature = "serde")]
405 is_config::<BitSet128>();
406 is_normal::<BitSet128Iter>();
407 }
408
409 #[test]
410 fn new() {
411 let mut bits = BitSet128::new();
412 bits.set(42);
413 assert!(bits[42u8]);
414 assert!(bits.test(42));
415 }
416
417 #[test]
418 fn const_new() {
419 const FLAGS: BitSet128 = BitSet128::new();
420 const EMPTY_CHECK: bool = FLAGS.is_empty(); assert_eq!(0, FLAGS.0);
422 #[allow(clippy::assertions_on_constants)]
423 {
424 assert!(EMPTY_CHECK);
425 }
426 }
427
428 #[test]
429 fn assign() {
430 let mut bits = BitSet128::new();
431 bits.set(42);
432 assert!(bits[42u8]);
433 assert!(bits.test(42));
434 let mask = bits;
435 assert!(mask.test(42));
436 }
437
438 #[test]
439 fn from() {
440 let _bits = BitSet128::from((0xab_u32, 0x12_u32));
441 }
442
443 #[test]
444 fn flip_all() {
445 let mut bitset = BitSet128::new();
446
447 bitset.set(0);
449 bitset.set(64);
450
451 bitset.flip_all();
452
453 assert!(!bitset.test(0));
455 assert!(!bitset.test(64));
456 assert!(bitset.test(1));
457 assert!(bitset.test(65));
458
459 let mut empty_set = BitSet128::new();
461 empty_set.flip_all(); let mut full_set = BitSet128::new();
464 full_set.set_all();
465
466 assert_eq!(empty_set, full_set);
467
468 empty_set.flip_all(); assert!(empty_set.is_empty());
470 }
471
472 #[test]
473 fn leading_zeros() {
474 let mut bitset = BitSet128::new();
475
476 assert_eq!(bitset.leading_zeros(), 128);
478
479 bitset.set(127);
481 assert_eq!(bitset.leading_zeros(), 0);
482
483 bitset.reset_all();
485 bitset.set(126);
486 assert_eq!(bitset.leading_zeros(), 1);
487
488 bitset.reset_all();
490 bitset.set(64);
491 assert_eq!(bitset.leading_zeros(), 63);
492
493 bitset.reset_all();
495 bitset.set(63);
496 assert_eq!(bitset.leading_zeros(), 64);
497
498 bitset.reset_all();
500 bitset.set(0);
501 assert_eq!(bitset.leading_zeros(), 127);
502 }
503
504 #[test]
505 fn last_set() {
506 let mut bitset = BitSet128::new();
507
508 assert_eq!(bitset.last_set(), None);
510
511 bitset.set(0);
513 assert_eq!(bitset.last_set(), Some(0));
514
515 bitset.set(10);
517 bitset.set(45);
518 assert_eq!(bitset.last_set(), Some(45));
519
520 bitset.reset_all();
522 bitset.set(63);
523 assert_eq!(bitset.last_set(), Some(63));
524
525 bitset.set(64);
527 assert_eq!(bitset.last_set(), Some(64));
528
529 bitset.set(100);
531 bitset.set(127);
532 assert_eq!(bitset.last_set(), Some(127));
533 }
534
535 #[test]
536 fn is_superset() {
537 let mut set_a = BitSet128::new();
538 let mut set_b = BitSet128::new();
539
540 assert!(set_a.is_superset(set_b));
542
543 set_a.set(10);
545 set_a.set(80);
546
547 set_b.set(10);
548
549 assert!(set_a.is_superset(set_b));
551 assert!(!set_b.is_superset(set_a));
553
554 set_b.set(80);
556 assert!(set_a.is_superset(set_b));
557
558 let mut set_c = BitSet128::new();
560 let mut set_d = BitSet128::new();
561 set_c.set(15); set_d.set(15);
564 set_d.set(95); assert!(!set_c.is_superset(set_d));
569 }
570
571 #[test]
572 fn intersects() {
573 let mut set_a = BitSet128::new();
574 let mut set_b = BitSet128::new();
575
576 assert!(!set_a.intersects(set_b));
578
579 set_a.set(15);
581 assert!(!set_a.intersects(set_b));
582
583 set_b.set(15);
585 assert!(set_a.intersects(set_b));
586 assert!(set_b.intersects(set_a));
587
588 set_a.reset_all();
590 set_b.reset_all();
591 set_a.set(10); set_b.set(80); assert!(!set_a.intersects(set_b));
594
595 set_a.set(80);
597 assert!(set_a.intersects(set_b));
598 }
599
600 #[test]
601 fn inplace_logical_ops() {
602 let mut set_a = BitSet128::new();
603 let mut set_b = BitSet128::new();
604
605 set_a.set(10);
607 set_a.set(70);
608
609 set_b.set(10);
610 set_b.set(80);
611
612 let mut result = set_a;
614 result &= set_b;
615 assert!(result.test(10));
616 assert!(!result.test(70));
617 assert!(!result.test(80));
618
619 let mut result = set_a;
621 result |= set_b;
622 assert!(result.test(10));
623 assert!(result.test(70));
624 assert!(result.test(80));
625
626 let mut result = set_a;
628 result ^= set_b;
629 assert!(!result.test(10)); assert!(result.test(70));
631 assert!(result.test(80));
632
633 let mut result = set_a;
635 result.and_not(set_b);
636 assert!(!result.test(10)); assert!(result.test(70)); assert!(!result.test(80)); }
640
641 #[test]
642 fn exercise() {
643 let mut system_flags = BitSet128::new();
644 let error_mask = BitSet128::new(); system_flags |= error_mask;
648
649 system_flags ^= error_mask;
651
652 let mut set_a = BitSet128::new();
656 set_a.set(10);
657 set_a.set(20);
658
659 let mut set_b = BitSet128::new();
660 set_b.set(20);
661 set_b.set(30);
662
663 let common = set_a & set_b;
665 assert!(!common.test(10));
666 assert!(common.test(20));
667 assert!(!common.test(30));
668
669 let all = set_a | set_b;
671 assert!(all.test(10));
672 assert!(all.test(20));
673 assert!(all.test(30));
674
675 let diff = set_a ^ set_b;
677 assert!(diff.test(10));
678 assert!(!diff.test(20));
679 assert!(diff.test(30));
680 }
681
682 #[test]
683 fn test_iterator_empty() {
684 let bitset = BitSet128::new();
685 let mut iter = bitset.iter();
686
687 assert_eq!(iter.size_hint(), (0, Some(0)));
688 assert_eq!(iter.next(), None);
689 }
690
691 #[test]
692 fn test_iterator_single_bits() {
693 let mut bitset = BitSet128::new();
695 bitset.set(0);
696 let mut iter = bitset.iter();
697 assert_eq!(iter.next(), Some(0));
698 assert_eq!(iter.next(), None);
699
700 bitset.reset_all();
702 bitset.set(63);
703 let mut iter = bitset.iter();
704 assert_eq!(iter.next(), Some(63));
705 assert_eq!(iter.next(), None);
706
707 bitset.reset_all();
709 bitset.set(64);
710 let mut iter = bitset.iter();
711 assert_eq!(iter.next(), Some(64));
712 assert_eq!(iter.next(), None);
713
714 bitset.reset_all();
716 bitset.set(127);
717 let mut iter = bitset.iter();
718 assert_eq!(iter.next(), Some(127));
719 assert_eq!(iter.next(), None);
720 }
721
722 #[test]
723 fn test_iterator_multiple_scattered_bits() {
724 let mut bitset = BitSet128::new();
725 let expected_indices = [5, 12, 63, 64, 99, 127];
727
728 for &idx in &expected_indices {
729 bitset.set(idx);
730 }
731
732 let mut iter = bitset.iter();
734 assert_eq!(iter.size_hint(), (expected_indices.len(), Some(expected_indices.len())));
735
736 for &expected in &expected_indices {
738 assert_eq!(iter.next(), Some(expected));
739 }
740 assert_eq!(iter.next(), None);
741 }
742
743 #[test]
744 fn test_iterator_size_hint_drainage() {
745 let mut bitset = BitSet128::new();
746 bitset.set(10);
747 bitset.set(90);
748
749 let mut iter = bitset.iter();
750 assert_eq!(iter.size_hint(), (2, Some(2)));
751 assert_eq!(iter.len(), 2); assert_eq!(iter.next(), Some(10));
754 assert_eq!(iter.size_hint(), (1, Some(1)));
755 assert_eq!(iter.len(), 1);
756
757 assert_eq!(iter.next(), Some(90));
758 assert_eq!(iter.size_hint(), (0, Some(0)));
759 assert_eq!(iter.len(), 0);
760
761 assert_eq!(iter.next(), None);
762 }
763
764 #[test]
765 fn test_iterator_all_bits_set() {
766 let mut bitset = BitSet128::new();
767 bitset.set_all();
768
769 let mut count = 0;
770 #[allow(clippy::cast_possible_truncation)]
771 for (expected_idx, actual_idx) in bitset.iter().enumerate() {
772 assert_eq!(expected_idx as u8, actual_idx);
773 count += 1;
774 }
775 assert_eq!(count, 128);
776 }
777
778 #[test]
779 fn test_consuming_into_iter() {
780 let mut bitset = BitSet128::new();
781 bitset.set(42);
782
783 let mut count = 0;
784 for idx in bitset {
785 assert_eq!(idx, 42);
786 count += 1;
787 }
788 assert_eq!(count, 1);
789 }
790
791 #[test]
792 fn from_iterator() {
793 let indices = [5, 63, 64, 120];
795 let bitset: BitSet128 = indices.into_iter().collect();
796
797 assert!(bitset.test(5));
798 assert!(bitset.test(63));
799 assert!(bitset.test(64));
800 assert!(bitset.test(120));
801 assert_eq!(bitset.count_ones(), 4);
802
803 let invalid_indices = [20, 200, 255];
805 let safe_bitset: BitSet128 = invalid_indices.into_iter().collect();
806
807 assert!(safe_bitset.test(20));
808 assert_eq!(safe_bitset.count_ones(), 1); }
810
811 #[test]
812 fn empty_and_full() {
813 let empty = BitSet128::new();
814 assert_eq!(empty.iter().count(), 0);
815
816 let mut full = BitSet128::new();
817 full.set_all();
818 assert_eq!(full.iter().count(), 128);
819 }
820}