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 pub const fn new() -> Self {
17 Self(0, 0)
18 }
19}
20
21#[cfg(feature = "serde")]
22impl PostcardValue<'_> for BitSet128 {}
23
24impl Default for BitSet128 {
25 fn default() -> Self {
26 Self::new()
27 }
28}
29
30impl BitSet128 {
31 #[inline]
33 pub fn reset_all(&mut self) {
34 self.0 = 0;
35 self.1 = 0;
36 }
37
38 #[inline]
40 pub fn reset(&mut self, index: u8) {
41 if index < 64 {
42 self.0 &= !(1u64 << index);
43 } else if index < 128 {
44 self.1 &= !(1u64 << (index - 64));
45 }
46 }
47
48 #[inline]
50 pub fn set_all(&mut self) {
51 self.0 = u64::MAX;
52 self.1 = u64::MAX;
53 }
54
55 #[inline]
57 pub fn set(&mut self, index: u8) {
58 if index < 64 {
59 self.0 |= 1u64 << index;
60 } else if index < 128 {
61 self.1 |= 1u64 << (index - 64);
62 }
63 }
64
65 #[inline]
67 pub fn flip(&mut self, index: u8) {
68 if index < 64 {
69 self.0 ^= 1u64 << index;
70 } else if index < 128 {
71 self.1 ^= 1u64 << (index - 64);
72 }
73 }
74
75 #[inline]
77 pub fn flip_all(&mut self) {
78 self.0 = !self.0;
79 self.1 = !self.1;
80 }
81
82 #[inline]
85 pub fn and_not(&mut self, other: Self) {
86 self.0 &= !other.0;
87 self.1 &= !other.1;
88 }
89
90 #[inline]
93 pub fn test(&self, index: u8) -> bool {
94 if index < 64 {
95 (self.0 & (1u64 << index)) != 0
96 } else if index < 128 {
97 (self.1 & (1u64 << (index - 64))) != 0
98 } else {
99 false
100 }
101 }
102
103 #[inline]
105 pub const fn count_ones(&self) -> u32 {
106 self.0.count_ones() + self.1.count_ones()
107 }
108
109 #[inline]
112 pub const fn leading_zeros(&self) -> u32 {
113 if self.1 == 0 {
116 64 + self.0.leading_zeros()
117 } else {
118 self.1.leading_zeros()
121 }
122 }
123
124 #[inline]
126 pub const fn is_empty(&self) -> bool {
127 self.0 == 0 && self.1 == 0
128 }
129 #[inline]
132 pub const fn last_set(&self) -> Option<u8> {
133 let leading = self.leading_zeros();
134 if leading == 128 {
135 None
136 } else {
137 #[allow(clippy::cast_possible_truncation)]
141 Some((127 - leading) as u8)
142 }
143 }
144
145 #[inline]
147 pub const fn is_superset(&self, other: &Self) -> bool {
148 (self.0 & other.0) == other.0 && (self.1 & other.1) == other.1
151 }
152
153 #[inline]
155 pub const fn is_subset(&self, other: &BitSet128) -> bool {
156 other.is_superset(self)
157 }
158
159 #[inline]
162 pub const fn intersects(&self, other: &Self) -> bool {
163 (self.0 & other.0) != 0 || (self.1 & other.1) != 0
166 }
167
168 #[inline]
170 pub fn iter(&self) -> BitSet128Iter {
171 self.into_iter()
172 }
173}
174
175impl BitOr for BitSet128 {
178 type Output = Self;
179 fn bitor(self, rhs: Self) -> Self::Output {
180 Self(self.0 | rhs.0, self.1 | rhs.1)
181 }
182}
183
184impl BitAnd for BitSet128 {
185 type Output = Self;
186 fn bitand(self, rhs: Self) -> Self::Output {
187 Self(self.0 & rhs.0, self.1 & rhs.1)
188 }
189}
190
191impl BitXor for BitSet128 {
192 type Output = Self;
193 fn bitxor(self, rhs: Self) -> Self::Output {
194 Self(self.0 ^ rhs.0, self.1 ^ rhs.1)
195 }
196}
197
198impl BitOrAssign for BitSet128 {
199 fn bitor_assign(&mut self, rhs: Self) {
200 self.0 |= rhs.0;
201 self.1 |= rhs.1;
202 }
203}
204
205impl BitAndAssign for BitSet128 {
206 fn bitand_assign(&mut self, rhs: Self) {
207 self.0 &= rhs.0;
208 self.1 &= rhs.1;
209 }
210}
211
212impl BitXorAssign for BitSet128 {
213 fn bitxor_assign(&mut self, rhs: Self) {
214 self.0 ^= rhs.0;
215 self.1 ^= rhs.1;
216 }
217}
218
219impl Index<u8> for BitSet128 {
220 type Output = bool;
221
222 fn index(&self, index: u8) -> &Self::Output {
223 if self.test(index) { &true } else { &false }
225 }
226}
227
228impl Index<usize> for BitSet128 {
229 type Output = bool;
230
231 #[allow(clippy::cast_possible_truncation)]
232 fn index(&self, index: usize) -> &Self::Output {
233 if self.test(index as u8) { &true } else { &false }
235 }
236}
237
238impl From<u32> for BitSet128 {
240 #[inline]
241 fn from(a: u32) -> Self {
242 Self(u64::from(a), 0)
243 }
244}
245
246impl From<(u32, u32)> for BitSet128 {
248 #[inline]
249 fn from((a, b): (u32, u32)) -> Self {
250 Self(u64::from(a) << 32 | u64::from(b), 0)
251 }
252}
253
254impl From<(u32, u32, u32, u32)> for BitSet128 {
256 #[inline]
257 fn from((a, b, c, d): (u32, u32, u32, u32)) -> Self {
258 Self(u64::from(a) << 32 | u64::from(b), u64::from(c) << 32 | u64::from(d))
259 }
260}
261
262#[derive(Debug, Default, Eq, PartialEq)]
265pub struct BitSet128Iter(u64, u64);
266
267impl Iterator for BitSet128Iter {
269 type Item = u8;
270
271 fn next(&mut self) -> Option<Self::Item> {
272 if self.0 == 0 {
273 if self.1 == 0 {
274 None
275 } else {
276 #[allow(clippy::cast_possible_truncation)]
278 let index = self.1.trailing_zeros() as u8;
279 self.1 &= self.1 - 1;
281 Some(index + 64)
282 }
283 } else {
284 #[allow(clippy::cast_possible_truncation)]
286 let index = self.0.trailing_zeros() as u8;
287 self.0 &= self.0 - 1;
289 Some(index)
290 }
291 }
292
293 #[inline]
294 fn size_hint(&self) -> (usize, Option<usize>) {
295 let len = (self.0.count_ones() + self.1.count_ones()) as usize;
297 (len, Some(len))
298 }
299}
300
301impl ExactSizeIterator for BitSet128Iter {}
303impl core::iter::FusedIterator for BitSet128Iter {}
304
305impl IntoIterator for &BitSet128 {
307 type Item = u8;
308 type IntoIter = BitSet128Iter;
309
310 fn into_iter(self) -> Self::IntoIter {
311 BitSet128Iter(self.0, self.1)
314 }
315}
316
317impl IntoIterator for BitSet128 {
319 type Item = u8;
320 type IntoIter = BitSet128Iter;
321
322 fn into_iter(self) -> Self::IntoIter {
323 BitSet128Iter(self.0, self.1)
326 }
327}
328
329impl FromIterator<u8> for BitSet128 {
331 fn from_iter<I: IntoIterator<Item = u8>>(iter: I) -> Self {
332 let mut bitset = Self::new();
333 for index in iter {
334 bitset.set(index);
335 }
336 bitset
337 }
338}
339
340impl Extend<u8> for BitSet128 {
341 fn extend<I: IntoIterator<Item = u8>>(&mut self, iter: I) {
342 for index in iter {
343 self.set(index);
344 }
345 }
346}
347
348impl fmt::Binary for BitSet128 {
351 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
352 if f.alternate() {
354 f.write_str("0b")?;
355 }
356 for i in (0..64).rev() {
359 let val = (self.1 >> i) & 1;
360 write!(f, "{val}")?;
361 }
362 for i in (0..64).rev() {
364 let val = (self.0 >> i) & 1;
365 write!(f, "{val}")?;
366 }
367
368 Ok(())
369 }
370}
371
372impl fmt::UpperHex for BitSet128 {
373 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
374 if f.alternate() {
375 f.write_str("0x")?;
376 }
377 write!(f, "{:016X}{:016X}", self.1, self.0)
378 }
379}
380
381#[cfg(test)]
382mod tests {
383 use super::*;
384
385 fn is_normal<T: Sized + Send + Sync + Unpin>() {}
386 fn is_full<T: Sized + Send + Sync + Unpin + Copy + Clone + Default + PartialEq>() {}
387 #[cfg(feature = "serde")]
388 fn is_config<T: Serialize + for<'a> Deserialize<'a>>() {}
389
390 #[test]
391 fn normal_types() {
392 is_full::<BitSet128>();
393 #[cfg(feature = "serde")]
394 is_config::<BitSet128>();
395 is_normal::<BitSet128Iter>();
396 }
397 #[test]
398 fn new() {
399 let mut bits = BitSet128::new();
400 bits.set(42);
401 assert!(bits[42u8]);
402 assert!(bits.test(42));
403 }
404 #[allow(unused)]
405 #[test]
406 fn const_new() {
407 const FLAGS: BitSet128 = BitSet128::new();
408 const EMPTY_CHECK: bool = FLAGS.is_empty(); }
410 #[test]
411 fn assign() {
412 let mut bits = BitSet128::new();
413 bits.set(42);
414 assert!(bits[42u8]);
415 assert!(bits.test(42));
416 let mask = bits;
417 assert!(mask.test(42));
418 }
419 #[test]
420 fn from() {
421 let _bits = BitSet128::from((0xab_u32, 0x12_u32));
422 }
423 #[test]
424 fn flip_all() {
425 let mut bitset = BitSet128::new();
426
427 bitset.set(0);
429 bitset.set(64);
430
431 bitset.flip_all();
432
433 assert!(!bitset.test(0));
435 assert!(!bitset.test(64));
436 assert!(bitset.test(1));
437 assert!(bitset.test(65));
438
439 let mut empty_set = BitSet128::new();
441 empty_set.flip_all(); let mut full_set = BitSet128::new();
444 full_set.set_all();
445
446 assert_eq!(empty_set, full_set);
447
448 empty_set.flip_all(); assert!(empty_set.is_empty());
450 }
451 #[test]
452 fn leading_zeros() {
453 let mut bitset = BitSet128::new();
454
455 assert_eq!(bitset.leading_zeros(), 128);
457
458 bitset.set(127);
460 assert_eq!(bitset.leading_zeros(), 0);
461
462 bitset.reset_all();
464 bitset.set(126);
465 assert_eq!(bitset.leading_zeros(), 1);
466
467 bitset.reset_all();
469 bitset.set(64);
470 assert_eq!(bitset.leading_zeros(), 63);
471
472 bitset.reset_all();
474 bitset.set(63);
475 assert_eq!(bitset.leading_zeros(), 64);
476
477 bitset.reset_all();
479 bitset.set(0);
480 assert_eq!(bitset.leading_zeros(), 127);
481 }
482 #[test]
483 fn last_set() {
484 let mut bitset = BitSet128::new();
485
486 assert_eq!(bitset.last_set(), None);
488
489 bitset.set(0);
491 assert_eq!(bitset.last_set(), Some(0));
492
493 bitset.set(10);
495 bitset.set(45);
496 assert_eq!(bitset.last_set(), Some(45));
497
498 bitset.reset_all();
500 bitset.set(63);
501 assert_eq!(bitset.last_set(), Some(63));
502
503 bitset.set(64);
505 assert_eq!(bitset.last_set(), Some(64));
506
507 bitset.set(100);
509 bitset.set(127);
510 assert_eq!(bitset.last_set(), Some(127));
511 }
512 #[test]
513 fn is_superset() {
514 let mut set_a = BitSet128::new();
515 let mut set_b = BitSet128::new();
516
517 assert!(set_a.is_superset(&set_b));
519
520 set_a.set(10);
522 set_a.set(80);
523
524 set_b.set(10);
525
526 assert!(set_a.is_superset(&set_b));
528 assert!(!set_b.is_superset(&set_a));
530
531 set_b.set(80);
533 assert!(set_a.is_superset(&set_b));
534
535 let mut set_c = BitSet128::new();
537 let mut set_d = BitSet128::new();
538 set_c.set(15); set_d.set(15);
541 set_d.set(95); assert!(!set_c.is_superset(&set_d));
546 }
547 #[test]
548 fn intersects() {
549 let mut set_a = BitSet128::new();
550 let mut set_b = BitSet128::new();
551
552 assert!(!set_a.intersects(&set_b));
554
555 set_a.set(15);
557 assert!(!set_a.intersects(&set_b));
558
559 set_b.set(15);
561 assert!(set_a.intersects(&set_b));
562 assert!(set_b.intersects(&set_a));
563
564 set_a.reset_all();
566 set_b.reset_all();
567 set_a.set(10); set_b.set(80); assert!(!set_a.intersects(&set_b));
570
571 set_a.set(80);
573 assert!(set_a.intersects(&set_b));
574 }
575 #[test]
576 fn inplace_logical_ops() {
577 let mut set_a = BitSet128::new();
578 let mut set_b = BitSet128::new();
579
580 set_a.set(10);
582 set_a.set(70);
583
584 set_b.set(10);
585 set_b.set(80);
586
587 let mut result = set_a;
589 result &= set_b;
590 assert!(result.test(10));
591 assert!(!result.test(70));
592 assert!(!result.test(80));
593
594 let mut result = set_a;
596 result |= set_b;
597 assert!(result.test(10));
598 assert!(result.test(70));
599 assert!(result.test(80));
600
601 let mut result = set_a;
603 result ^= set_b;
604 assert!(!result.test(10)); assert!(result.test(70));
606 assert!(result.test(80));
607
608 let mut result = set_a;
610 result.and_not(set_b);
611 assert!(!result.test(10)); assert!(result.test(70)); assert!(!result.test(80)); }
615 #[test]
616 fn exercise() {
617 let mut system_flags = BitSet128::new();
618 let error_mask = BitSet128::new(); system_flags |= error_mask;
622
623 system_flags ^= error_mask;
625
626 let mut set_a = BitSet128::new();
630 set_a.set(10);
631 set_a.set(20);
632
633 let mut set_b = BitSet128::new();
634 set_b.set(20);
635 set_b.set(30);
636
637 let common = set_a & set_b;
639 assert!(!common.test(10));
640 assert!(common.test(20));
641 assert!(!common.test(30));
642
643 let all = set_a | set_b;
645 assert!(all.test(10));
646 assert!(all.test(20));
647 assert!(all.test(30));
648
649 let diff = set_a ^ set_b;
651 assert!(diff.test(10));
652 assert!(!diff.test(20));
653 assert!(diff.test(30));
654 }
655
656 #[test]
657 fn test_iterator_empty() {
658 let bitset = BitSet128::new();
659 let mut iter = bitset.iter();
660
661 assert_eq!(iter.size_hint(), (0, Some(0)));
662 assert_eq!(iter.next(), None);
663 }
664
665 #[test]
666 fn test_iterator_single_bits() {
667 let mut bitset = BitSet128::new();
669 bitset.set(0);
670 let mut iter = bitset.iter();
671 assert_eq!(iter.next(), Some(0));
672 assert_eq!(iter.next(), None);
673
674 bitset.reset_all();
676 bitset.set(63);
677 let mut iter = bitset.iter();
678 assert_eq!(iter.next(), Some(63));
679 assert_eq!(iter.next(), None);
680
681 bitset.reset_all();
683 bitset.set(64);
684 let mut iter = bitset.iter();
685 assert_eq!(iter.next(), Some(64));
686 assert_eq!(iter.next(), None);
687
688 bitset.reset_all();
690 bitset.set(127);
691 let mut iter = bitset.iter();
692 assert_eq!(iter.next(), Some(127));
693 assert_eq!(iter.next(), None);
694 }
695
696 #[test]
697 fn test_iterator_multiple_scattered_bits() {
698 let mut bitset = BitSet128::new();
699 let expected_indices = [5, 12, 63, 64, 99, 127];
701
702 for &idx in &expected_indices {
703 bitset.set(idx);
704 }
705
706 let mut iter = bitset.iter();
708 assert_eq!(iter.size_hint(), (expected_indices.len(), Some(expected_indices.len())));
709
710 for &expected in &expected_indices {
712 assert_eq!(iter.next(), Some(expected));
713 }
714 assert_eq!(iter.next(), None);
715 }
716
717 #[test]
718 fn test_iterator_size_hint_drainage() {
719 let mut bitset = BitSet128::new();
720 bitset.set(10);
721 bitset.set(90);
722
723 let mut iter = bitset.iter();
724 assert_eq!(iter.size_hint(), (2, Some(2)));
725 assert_eq!(iter.len(), 2); assert_eq!(iter.next(), Some(10));
728 assert_eq!(iter.size_hint(), (1, Some(1)));
729 assert_eq!(iter.len(), 1);
730
731 assert_eq!(iter.next(), Some(90));
732 assert_eq!(iter.size_hint(), (0, Some(0)));
733 assert_eq!(iter.len(), 0);
734
735 assert_eq!(iter.next(), None);
736 }
737
738 #[test]
739 fn test_iterator_all_bits_set() {
740 let mut bitset = BitSet128::new();
741 bitset.set_all();
742
743 let mut count = 0;
744 #[allow(clippy::cast_possible_truncation)]
745 for (expected_idx, actual_idx) in bitset.iter().enumerate() {
746 assert_eq!(expected_idx as u8, actual_idx);
747 count += 1;
748 }
749 assert_eq!(count, 128);
750 }
751
752 #[test]
753 fn test_consuming_into_iter() {
754 let mut bitset = BitSet128::new();
755 bitset.set(42);
756
757 let mut count = 0;
758 for idx in bitset {
759 assert_eq!(idx, 42);
760 count += 1;
761 }
762 assert_eq!(count, 1);
763 }
764
765 #[test]
766 fn from_iterator() {
767 let indices = [5, 63, 64, 120];
769 let bitset: BitSet128 = indices.into_iter().collect();
770
771 assert!(bitset.test(5));
772 assert!(bitset.test(63));
773 assert!(bitset.test(64));
774 assert!(bitset.test(120));
775 assert_eq!(bitset.count_ones(), 4);
776
777 let invalid_indices = [20, 200, 255];
779 let safe_bitset: BitSet128 = invalid_indices.into_iter().collect();
780
781 assert!(safe_bitset.test(20));
782 assert_eq!(safe_bitset.count_ones(), 1); }
784 #[test]
785 fn empty_and_full() {
786 let empty = BitSet128::new();
787 assert_eq!(empty.iter().count(), 0);
788
789 let mut full = BitSet128::new();
790 full.set_all();
791 assert_eq!(full.iter().count(), 128);
792 }
793}