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, rhs: Self) -> Self::Output {
190 Self(self.0 | rhs.0, self.1 | rhs.1)
191 }
192}
193
194impl BitAnd for BitSet128 {
195 type Output = Self;
196 fn bitand(self, rhs: Self) -> Self::Output {
197 Self(self.0 & rhs.0, self.1 & rhs.1)
198 }
199}
200
201impl BitXor for BitSet128 {
202 type Output = Self;
203 fn bitxor(self, rhs: Self) -> Self::Output {
204 Self(self.0 ^ rhs.0, self.1 ^ rhs.1)
205 }
206}
207
208impl BitOrAssign for BitSet128 {
209 fn bitor_assign(&mut self, rhs: Self) {
210 self.0 |= rhs.0;
211 self.1 |= rhs.1;
212 }
213}
214
215impl BitAndAssign for BitSet128 {
216 fn bitand_assign(&mut self, rhs: Self) {
217 self.0 &= rhs.0;
218 self.1 &= rhs.1;
219 }
220}
221
222impl BitXorAssign for BitSet128 {
223 fn bitxor_assign(&mut self, rhs: Self) {
224 self.0 ^= rhs.0;
225 self.1 ^= rhs.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)]
275pub struct BitSet128Iter(u64, u64);
276
277impl Iterator for BitSet128Iter {
279 type Item = u8;
280
281 fn next(&mut self) -> Option<Self::Item> {
282 if self.0 == 0 {
283 if self.1 == 0 {
284 None
285 } else {
286 #[allow(clippy::cast_possible_truncation)]
288 let index = self.1.trailing_zeros() as u8;
289 self.1 &= self.1 - 1;
291 Some(index + 64)
292 }
293 } else {
294 #[allow(clippy::cast_possible_truncation)]
296 let index = self.0.trailing_zeros() as u8;
297 self.0 &= self.0 - 1;
299 Some(index)
300 }
301 }
302
303 #[inline]
304 fn size_hint(&self) -> (usize, Option<usize>) {
305 let len = (self.0.count_ones() + self.1.count_ones()) as usize;
307 (len, Some(len))
308 }
309}
310
311impl ExactSizeIterator for BitSet128Iter {}
313impl core::iter::FusedIterator for BitSet128Iter {}
314
315impl IntoIterator for &BitSet128 {
317 type Item = u8;
318 type IntoIter = BitSet128Iter;
319
320 fn into_iter(self) -> Self::IntoIter {
321 BitSet128Iter(self.0, self.1)
324 }
325}
326
327impl IntoIterator for BitSet128 {
329 type Item = u8;
330 type IntoIter = BitSet128Iter;
331
332 fn into_iter(self) -> Self::IntoIter {
333 BitSet128Iter(self.0, self.1)
336 }
337}
338
339impl FromIterator<u8> for BitSet128 {
341 fn from_iter<I: IntoIterator<Item = u8>>(iter: I) -> Self {
342 let mut bitset = Self::new();
343 for index in iter {
344 bitset.set(index);
345 }
346 bitset
347 }
348}
349
350impl Extend<u8> for BitSet128 {
351 fn extend<I: IntoIterator<Item = u8>>(&mut self, iter: I) {
352 for index in iter {
353 self.set(index);
354 }
355 }
356}
357
358impl fmt::Binary for BitSet128 {
361 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
362 if f.alternate() {
364 f.write_str("0b")?;
365 }
366 for i in (0..64).rev() {
369 let val = (self.1 >> i) & 1;
370 write!(f, "{val}")?;
371 }
372 for i in (0..64).rev() {
374 let val = (self.0 >> i) & 1;
375 write!(f, "{val}")?;
376 }
377
378 Ok(())
379 }
380}
381
382impl fmt::UpperHex for BitSet128 {
383 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
384 if f.alternate() {
385 f.write_str("0x")?;
386 }
387 write!(f, "{:016X}{:016X}", self.1, self.0)
388 }
389}
390
391#[cfg(test)]
392mod tests {
393 use super::*;
394
395 fn is_normal<T: Sized + Send + Sync + Unpin>() {}
396 fn is_full<T: Sized + Send + Sync + Unpin + Copy + Clone + Default + PartialEq>() {}
397 #[cfg(feature = "serde")]
398 fn is_config<T: Serialize + for<'a> Deserialize<'a>>() {}
399
400 #[test]
401 fn normal_types() {
402 is_full::<BitSet128>();
403 #[cfg(feature = "serde")]
404 is_config::<BitSet128>();
405 is_normal::<BitSet128Iter>();
406 }
407 #[test]
408 fn new() {
409 let mut bits = BitSet128::new();
410 bits.set(42);
411 assert!(bits[42u8]);
412 assert!(bits.test(42));
413 }
414 #[allow(unused)]
415 #[test]
416 fn const_new() {
417 const FLAGS: BitSet128 = BitSet128::new();
418 const EMPTY_CHECK: bool = FLAGS.is_empty(); }
420 #[test]
421 fn assign() {
422 let mut bits = BitSet128::new();
423 bits.set(42);
424 assert!(bits[42u8]);
425 assert!(bits.test(42));
426 let mask = bits;
427 assert!(mask.test(42));
428 }
429 #[test]
430 fn from() {
431 let _bits = BitSet128::from((0xab_u32, 0x12_u32));
432 }
433 #[test]
434 fn flip_all() {
435 let mut bitset = BitSet128::new();
436
437 bitset.set(0);
439 bitset.set(64);
440
441 bitset.flip_all();
442
443 assert!(!bitset.test(0));
445 assert!(!bitset.test(64));
446 assert!(bitset.test(1));
447 assert!(bitset.test(65));
448
449 let mut empty_set = BitSet128::new();
451 empty_set.flip_all(); let mut full_set = BitSet128::new();
454 full_set.set_all();
455
456 assert_eq!(empty_set, full_set);
457
458 empty_set.flip_all(); assert!(empty_set.is_empty());
460 }
461 #[test]
462 fn leading_zeros() {
463 let mut bitset = BitSet128::new();
464
465 assert_eq!(bitset.leading_zeros(), 128);
467
468 bitset.set(127);
470 assert_eq!(bitset.leading_zeros(), 0);
471
472 bitset.reset_all();
474 bitset.set(126);
475 assert_eq!(bitset.leading_zeros(), 1);
476
477 bitset.reset_all();
479 bitset.set(64);
480 assert_eq!(bitset.leading_zeros(), 63);
481
482 bitset.reset_all();
484 bitset.set(63);
485 assert_eq!(bitset.leading_zeros(), 64);
486
487 bitset.reset_all();
489 bitset.set(0);
490 assert_eq!(bitset.leading_zeros(), 127);
491 }
492 #[test]
493 fn last_set() {
494 let mut bitset = BitSet128::new();
495
496 assert_eq!(bitset.last_set(), None);
498
499 bitset.set(0);
501 assert_eq!(bitset.last_set(), Some(0));
502
503 bitset.set(10);
505 bitset.set(45);
506 assert_eq!(bitset.last_set(), Some(45));
507
508 bitset.reset_all();
510 bitset.set(63);
511 assert_eq!(bitset.last_set(), Some(63));
512
513 bitset.set(64);
515 assert_eq!(bitset.last_set(), Some(64));
516
517 bitset.set(100);
519 bitset.set(127);
520 assert_eq!(bitset.last_set(), Some(127));
521 }
522 #[test]
523 fn is_superset() {
524 let mut set_a = BitSet128::new();
525 let mut set_b = BitSet128::new();
526
527 assert!(set_a.is_superset(&set_b));
529
530 set_a.set(10);
532 set_a.set(80);
533
534 set_b.set(10);
535
536 assert!(set_a.is_superset(&set_b));
538 assert!(!set_b.is_superset(&set_a));
540
541 set_b.set(80);
543 assert!(set_a.is_superset(&set_b));
544
545 let mut set_c = BitSet128::new();
547 let mut set_d = BitSet128::new();
548 set_c.set(15); set_d.set(15);
551 set_d.set(95); assert!(!set_c.is_superset(&set_d));
556 }
557 #[test]
558 fn intersects() {
559 let mut set_a = BitSet128::new();
560 let mut set_b = BitSet128::new();
561
562 assert!(!set_a.intersects(&set_b));
564
565 set_a.set(15);
567 assert!(!set_a.intersects(&set_b));
568
569 set_b.set(15);
571 assert!(set_a.intersects(&set_b));
572 assert!(set_b.intersects(&set_a));
573
574 set_a.reset_all();
576 set_b.reset_all();
577 set_a.set(10); set_b.set(80); assert!(!set_a.intersects(&set_b));
580
581 set_a.set(80);
583 assert!(set_a.intersects(&set_b));
584 }
585 #[test]
586 fn inplace_logical_ops() {
587 let mut set_a = BitSet128::new();
588 let mut set_b = BitSet128::new();
589
590 set_a.set(10);
592 set_a.set(70);
593
594 set_b.set(10);
595 set_b.set(80);
596
597 let mut result = set_a;
599 result &= set_b;
600 assert!(result.test(10));
601 assert!(!result.test(70));
602 assert!(!result.test(80));
603
604 let mut result = set_a;
606 result |= set_b;
607 assert!(result.test(10));
608 assert!(result.test(70));
609 assert!(result.test(80));
610
611 let mut result = set_a;
613 result ^= set_b;
614 assert!(!result.test(10)); assert!(result.test(70));
616 assert!(result.test(80));
617
618 let mut result = set_a;
620 result.and_not(set_b);
621 assert!(!result.test(10)); assert!(result.test(70)); assert!(!result.test(80)); }
625 #[test]
626 fn exercise() {
627 let mut system_flags = BitSet128::new();
628 let error_mask = BitSet128::new(); system_flags |= error_mask;
632
633 system_flags ^= error_mask;
635
636 let mut set_a = BitSet128::new();
640 set_a.set(10);
641 set_a.set(20);
642
643 let mut set_b = BitSet128::new();
644 set_b.set(20);
645 set_b.set(30);
646
647 let common = set_a & set_b;
649 assert!(!common.test(10));
650 assert!(common.test(20));
651 assert!(!common.test(30));
652
653 let all = set_a | set_b;
655 assert!(all.test(10));
656 assert!(all.test(20));
657 assert!(all.test(30));
658
659 let diff = set_a ^ set_b;
661 assert!(diff.test(10));
662 assert!(!diff.test(20));
663 assert!(diff.test(30));
664 }
665
666 #[test]
667 fn test_iterator_empty() {
668 let bitset = BitSet128::new();
669 let mut iter = bitset.iter();
670
671 assert_eq!(iter.size_hint(), (0, Some(0)));
672 assert_eq!(iter.next(), None);
673 }
674
675 #[test]
676 fn test_iterator_single_bits() {
677 let mut bitset = BitSet128::new();
679 bitset.set(0);
680 let mut iter = bitset.iter();
681 assert_eq!(iter.next(), Some(0));
682 assert_eq!(iter.next(), None);
683
684 bitset.reset_all();
686 bitset.set(63);
687 let mut iter = bitset.iter();
688 assert_eq!(iter.next(), Some(63));
689 assert_eq!(iter.next(), None);
690
691 bitset.reset_all();
693 bitset.set(64);
694 let mut iter = bitset.iter();
695 assert_eq!(iter.next(), Some(64));
696 assert_eq!(iter.next(), None);
697
698 bitset.reset_all();
700 bitset.set(127);
701 let mut iter = bitset.iter();
702 assert_eq!(iter.next(), Some(127));
703 assert_eq!(iter.next(), None);
704 }
705
706 #[test]
707 fn test_iterator_multiple_scattered_bits() {
708 let mut bitset = BitSet128::new();
709 let expected_indices = [5, 12, 63, 64, 99, 127];
711
712 for &idx in &expected_indices {
713 bitset.set(idx);
714 }
715
716 let mut iter = bitset.iter();
718 assert_eq!(iter.size_hint(), (expected_indices.len(), Some(expected_indices.len())));
719
720 for &expected in &expected_indices {
722 assert_eq!(iter.next(), Some(expected));
723 }
724 assert_eq!(iter.next(), None);
725 }
726
727 #[test]
728 fn test_iterator_size_hint_drainage() {
729 let mut bitset = BitSet128::new();
730 bitset.set(10);
731 bitset.set(90);
732
733 let mut iter = bitset.iter();
734 assert_eq!(iter.size_hint(), (2, Some(2)));
735 assert_eq!(iter.len(), 2); assert_eq!(iter.next(), Some(10));
738 assert_eq!(iter.size_hint(), (1, Some(1)));
739 assert_eq!(iter.len(), 1);
740
741 assert_eq!(iter.next(), Some(90));
742 assert_eq!(iter.size_hint(), (0, Some(0)));
743 assert_eq!(iter.len(), 0);
744
745 assert_eq!(iter.next(), None);
746 }
747
748 #[test]
749 fn test_iterator_all_bits_set() {
750 let mut bitset = BitSet128::new();
751 bitset.set_all();
752
753 let mut count = 0;
754 #[allow(clippy::cast_possible_truncation)]
755 for (expected_idx, actual_idx) in bitset.iter().enumerate() {
756 assert_eq!(expected_idx as u8, actual_idx);
757 count += 1;
758 }
759 assert_eq!(count, 128);
760 }
761
762 #[test]
763 fn test_consuming_into_iter() {
764 let mut bitset = BitSet128::new();
765 bitset.set(42);
766
767 let mut count = 0;
768 for idx in bitset {
769 assert_eq!(idx, 42);
770 count += 1;
771 }
772 assert_eq!(count, 1);
773 }
774
775 #[test]
776 fn from_iterator() {
777 let indices = [5, 63, 64, 120];
779 let bitset: BitSet128 = indices.into_iter().collect();
780
781 assert!(bitset.test(5));
782 assert!(bitset.test(63));
783 assert!(bitset.test(64));
784 assert!(bitset.test(120));
785 assert_eq!(bitset.count_ones(), 4);
786
787 let invalid_indices = [20, 200, 255];
789 let safe_bitset: BitSet128 = invalid_indices.into_iter().collect();
790
791 assert!(safe_bitset.test(20));
792 assert_eq!(safe_bitset.count_ones(), 1); }
794 #[test]
795 fn empty_and_full() {
796 let empty = BitSet128::new();
797 assert_eq!(empty.iter().count(), 0);
798
799 let mut full = BitSet128::new();
800 full.set_all();
801 assert_eq!(full.iter().count(), 128);
802 }
803}