simple_bitset/
bitset64.rs1use 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)]
12#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
13pub struct BitSet64(u64);
14
15impl BitSet64 {
16 #[must_use]
18 pub const fn new() -> Self {
19 Self(0)
20 }
21}
22
23#[cfg(feature = "serde")]
24impl PostcardValue<'_> for BitSet64 {}
25
26impl Default for BitSet64 {
27 fn default() -> Self {
28 Self::new()
29 }
30}
31
32impl BitSet64 {
33 #[inline]
35 pub fn reset_all(&mut self) {
36 self.0 = 0;
37 }
38
39 #[inline]
41 pub fn reset(&mut self, index: u8) {
42 if index < 64 {
43 self.0 &= !(1u64 << index);
44 }
45 }
46
47 #[inline]
49 pub fn set_all(&mut self) {
50 self.0 = u64::MAX;
51 }
52
53 #[inline]
55 pub fn set(&mut self, index: u8) {
56 if index < 64 {
57 self.0 |= 1u64 << index;
58 }
59 }
60
61 #[inline]
63 pub fn flip(&mut self, index: u8) {
64 if index < 64 {
65 self.0 ^= 1u64 << index;
66 }
67 }
68
69 #[inline]
71 pub fn flip_all(&mut self) {
72 self.0 = !self.0;
73 }
74
75 #[inline]
78 pub fn and_not(&mut self, other: Self) {
79 self.0 &= !other.0;
80 }
81
82 #[inline]
85 #[must_use]
86 pub fn test(&self, index: u8) -> bool {
87 if index < 64 {
88 (self.0 & (1u64 << index)) != 0
89 } else {
90 false
91 }
92 }
93
94 #[allow(clippy::cast_possible_truncation)]
96 #[inline]
97 #[must_use]
98 pub fn bits_0_31(&self) -> u32 {
99 self.0 as u32
100 }
101
102 #[inline]
104 #[must_use]
105 pub fn bits_32_63(&self) -> u32 {
106 (self.0 >> 32) as u32
107 }
108
109 #[inline]
111 #[must_use]
112 pub const fn count_ones(&self) -> u32 {
113 self.0.count_ones()
114 }
115
116 #[inline]
119 #[must_use]
120 pub const fn leading_zeros(&self) -> u32 {
121 self.0.leading_zeros()
122 }
123
124 #[inline]
126 #[must_use]
127 pub const fn is_empty(&self) -> bool {
128 self.0 == 0
129 }
130
131 #[inline]
134 #[must_use]
135 pub const fn last_set(&self) -> Option<u8> {
136 if self.is_empty() {
137 None
138 } else {
139 #[allow(clippy::cast_possible_truncation)]
141 Some(63 - self.0.leading_zeros() as u8)
142 }
143 }
144
145 #[inline]
147 #[must_use]
148 pub const fn is_superset(&self, other: BitSet64) -> bool {
149 (self.0 & other.0) == other.0
152 }
153
154 #[inline]
156 #[must_use]
157 pub const fn is_subset(&self, other: BitSet64) -> bool {
158 other.is_superset(*self)
159 }
160
161 #[inline]
164 #[must_use]
165 pub const fn intersects(&self, other: Self) -> bool {
166 self.0 & other.0 != 0
169 }
170
171 #[inline]
173 #[must_use]
174 pub fn iter(&self) -> BitSet64Iter {
175 self.into_iter()
176 }
177}
178
179impl BitOr for BitSet64 {
182 type Output = Self;
183 fn bitor(self, other: Self) -> Self::Output {
184 Self(self.0 | other.0)
185 }
186}
187
188impl BitAnd for BitSet64 {
189 type Output = Self;
190 fn bitand(self, other: Self) -> Self::Output {
191 Self(self.0 & other.0)
192 }
193}
194
195impl BitXor for BitSet64 {
196 type Output = Self;
197 fn bitxor(self, other: Self) -> Self::Output {
198 Self(self.0 ^ other.0)
199 }
200}
201
202impl BitOrAssign for BitSet64 {
203 fn bitor_assign(&mut self, other: Self) {
204 self.0 |= other.0;
205 }
206}
207
208impl BitAndAssign for BitSet64 {
209 fn bitand_assign(&mut self, other: Self) {
210 self.0 &= other.0;
211 }
212}
213
214impl BitXorAssign for BitSet64 {
215 fn bitxor_assign(&mut self, other: Self) {
216 self.0 ^= other.0;
217 }
218}
219
220impl Index<u8> for BitSet64 {
221 type Output = bool;
222
223 fn index(&self, index: u8) -> &Self::Output {
224 if self.test(index) { &true } else { &false }
226 }
227}
228
229impl Index<usize> for BitSet64 {
230 type Output = bool;
231
232 #[allow(clippy::cast_possible_truncation)]
233 fn index(&self, index: usize) -> &Self::Output {
234 if self.test(index as u8) { &true } else { &false }
236 }
237}
238
239impl From<u32> for BitSet64 {
241 #[inline]
242 fn from(a: u32) -> Self {
243 Self(u64::from(a))
244 }
245}
246
247impl From<(u32, u32)> for BitSet64 {
249 #[inline]
250 fn from((a, b): (u32, u32)) -> Self {
251 Self(u64::from(a) << 32 | u64::from(b))
252 }
253}
254
255impl From<u64> for BitSet64 {
257 #[inline]
258 fn from(a: u64) -> Self {
259 Self(a)
260 }
261}
262
263#[derive(Debug, Default, Eq, PartialEq)]
267pub struct BitSet64Iter(u64);
268
269impl Iterator for BitSet64Iter {
271 type Item = u8;
272
273 fn next(&mut self) -> Option<Self::Item> {
274 if self.0 == 0 {
275 None
276 } else {
277 #[allow(clippy::cast_possible_truncation)]
279 let index = self.0.trailing_zeros() as u8;
280 self.0 &= self.0 - 1;
282 Some(index)
283 }
284 }
285
286 #[inline]
287 fn size_hint(&self) -> (usize, Option<usize>) {
288 let len = self.0.count_ones() as usize;
290 (len, Some(len))
291 }
292}
293
294impl ExactSizeIterator for BitSet64Iter {}
296impl core::iter::FusedIterator for BitSet64Iter {}
297
298impl IntoIterator for &BitSet64 {
300 type Item = u8;
301 type IntoIter = BitSet64Iter;
302
303 fn into_iter(self) -> Self::IntoIter {
304 BitSet64Iter(self.0)
307 }
308}
309
310impl IntoIterator for BitSet64 {
312 type Item = u8;
313 type IntoIter = BitSet64Iter;
314
315 fn into_iter(self) -> Self::IntoIter {
316 BitSet64Iter(self.0)
319 }
320}
321
322impl FromIterator<u8> for BitSet64 {
324 fn from_iter<I: IntoIterator<Item = u8>>(iter: I) -> Self {
325 let mut bitset = Self::new();
326 for index in iter {
327 bitset.set(index);
328 }
329 bitset
330 }
331}
332
333impl Extend<u8> for BitSet64 {
334 fn extend<I: IntoIterator<Item = u8>>(&mut self, iter: I) {
335 for index in iter {
336 self.set(index);
337 }
338 }
339}
340
341impl fmt::Binary for BitSet64 {
344 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
345 if f.alternate() {
347 f.write_str("0b")?;
348 }
349 for i in (0..64).rev() {
351 let val = (self.0 >> i) & 1;
352 write!(f, "{val}")?;
353 }
354
355 Ok(())
356 }
357}
358
359impl fmt::UpperHex for BitSet64 {
360 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
361 if f.alternate() {
362 f.write_str("0x")?;
363 }
364 write!(f, "{:016X}", self.0)
365 }
366}
367
368#[cfg(test)]
369mod tests {
370 use super::*;
371
372 fn is_normal<T: Sized + Send + Sync + Unpin>() {}
373 fn is_full<T: Sized + Send + Sync + Unpin + Copy + Clone + Default + PartialEq>() {}
374 #[cfg(feature = "serde")]
375 fn is_config<T: Serialize + for<'a> Deserialize<'a>>() {}
376
377 #[test]
378 fn normal_types() {
379 is_full::<BitSet64>();
380 #[cfg(feature = "serde")]
381 is_config::<BitSet64>();
382 is_normal::<BitSet64Iter>();
383 }
384
385 #[test]
386 fn new() {
387 let mut bits = BitSet64::new();
388 bits.set(42);
389 assert!(bits[42u8]);
390 assert!(bits.test(42));
391 }
392
393 #[test]
394 fn const_new() {
395 const FLAGS: BitSet64 = BitSet64::new();
396 const EMPTY_CHECK: bool = FLAGS.is_empty(); assert_eq!(0, FLAGS.0);
398 #[allow(clippy::assertions_on_constants)]
399 {
400 assert!(EMPTY_CHECK);
401 }
402 }
403
404 #[test]
405 fn assign() {
406 let mut bits = BitSet64::new();
407 bits.set(42);
408 assert!(bits[42u8]);
409 assert!(bits.test(42));
410 let mask = bits;
411 assert!(mask.test(42));
412 }
413
414 #[test]
415 fn from() {
416 let _bits = BitSet64::from((0xab_u32, 0x12_u32));
417 }
418
419 #[test]
420 fn flip_all() {
421 let mut bitset = BitSet64::new();
422
423 bitset.set(0);
425 bitset.set(32);
426
427 bitset.flip_all();
428
429 assert!(!bitset.test(0));
431 assert!(!bitset.test(32));
432 assert!(bitset.test(1));
433 assert!(bitset.test(33));
434
435 let mut empty_set = BitSet64::new();
437 empty_set.flip_all(); let mut full_set = BitSet64::new();
440 full_set.set_all();
441
442 assert_eq!(empty_set, full_set);
443
444 empty_set.flip_all(); assert!(empty_set.is_empty());
446 }
447
448 #[test]
449 fn leading_zeros() {
450 let mut bitset = BitSet64::new();
451
452 assert_eq!(bitset.leading_zeros(), 64);
454
455 bitset.set(63);
457 assert_eq!(bitset.leading_zeros(), 0);
458
459 bitset.reset_all();
461 bitset.set(62);
462 assert_eq!(bitset.leading_zeros(), 1);
463 }
464
465 #[test]
466 fn last_set() {
467 let mut bitset = BitSet64::new();
468
469 assert_eq!(bitset.last_set(), None);
471
472 bitset.set(0);
474 assert_eq!(bitset.last_set(), Some(0));
475
476 bitset.set(10);
478 bitset.set(45);
479 assert_eq!(bitset.last_set(), Some(45));
480
481 bitset.reset_all();
483 bitset.set(63);
484 assert_eq!(bitset.last_set(), Some(63));
485 }
486
487 #[test]
488 fn is_superset() {
489 let mut set_a = BitSet64::new();
490 let mut set_b = BitSet64::new();
491
492 assert!(set_a.is_superset(set_b));
494
495 set_a.set(10);
497 set_a.set(60);
498
499 set_b.set(10);
500
501 assert!(set_a.is_superset(set_b));
503 assert!(!set_b.is_superset(set_a));
505
506 set_b.set(60);
508 assert!(set_a.is_superset(set_b));
509
510 let mut set_c = BitSet64::new();
512 let mut set_d = BitSet64::new();
513 set_c.set(15); set_d.set(15);
516 set_d.set(55); assert!(!set_c.is_superset(set_d));
521 }
522
523 #[test]
524 fn intersects() {
525 let mut set_a = BitSet64::new();
526 let mut set_b = BitSet64::new();
527
528 assert!(!set_a.intersects(set_b));
530
531 set_a.set(15);
533 assert!(!set_a.intersects(set_b));
534
535 set_b.set(15);
537 assert!(set_a.intersects(set_b));
538 assert!(set_b.intersects(set_a));
539
540 set_a.reset_all();
542 set_b.reset_all();
543 set_a.set(10);
544 set_b.set(60);
545 assert!(!set_a.intersects(set_b));
546
547 set_a.set(60);
549 assert!(set_a.intersects(set_b));
550 }
551
552 #[test]
553 fn inplace_logical_ops() {
554 let mut set_a = BitSet64::new();
555 let mut set_b = BitSet64::new();
556
557 set_a.set(10);
559 set_a.set(50);
560
561 set_b.set(10);
562 set_b.set(60);
563
564 let mut result = set_a;
566 result &= set_b;
567 assert!(result.test(10));
568 assert!(!result.test(50));
569 assert!(!result.test(60));
570
571 let mut result = set_a;
573 result |= set_b;
574 assert!(result.test(10));
575 assert!(result.test(50));
576 assert!(result.test(60));
577
578 let mut result = set_a;
580 result ^= set_b;
581 assert!(!result.test(10)); assert!(result.test(50));
583 assert!(result.test(60));
584
585 let mut result = set_a;
587 result.and_not(set_b);
588 assert!(!result.test(10)); assert!(result.test(50)); assert!(!result.test(60)); }
592
593 #[test]
594 fn exercise() {
595 let mut system_flags = BitSet64::new();
596 let error_mask = BitSet64::new(); system_flags |= error_mask;
600
601 system_flags ^= error_mask;
603
604 system_flags &= BitSet64(0x0000_FFFF_FFFF_FFFF);
606
607 let mut set_a = BitSet64::new();
608 set_a.set(10);
609 set_a.set(20);
610
611 let mut set_b = BitSet64::new();
612 set_b.set(20);
613 set_b.set(30);
614
615 let common = set_a & set_b;
617 assert!(!common.test(10));
618 assert!(common.test(20));
619 assert!(!common.test(30));
620
621 let all = set_a | set_b;
623 assert!(all.test(10));
624 assert!(all.test(20));
625 assert!(all.test(30));
626
627 let diff = set_a ^ set_b;
629 assert!(diff.test(10));
630 assert!(!diff.test(20));
631 assert!(diff.test(30));
632 }
633
634 #[test]
635 fn iterator_consuming() {
636 let mut bits = BitSet64::new();
637 bits.set(2);
638 bits.set(10);
639
640 let mut sum = 0;
641 let mut count = 0;
642 for bit in &bits {
643 sum += bit;
644 count += 1;
645 }
646 assert_eq!(2, count);
647 assert_eq!(12, sum);
648 }
649
650 #[test]
651 fn into_iter_consuming() {
652 let mut bits = BitSet64::new();
653 bits.set(0);
654 bits.set(10);
655 bits.set(63);
656
657 let mut iter = bits.into_iter();
659
660 assert_eq!(iter.next(), Some(0));
661 assert_eq!(iter.next(), Some(10));
662 assert_eq!(iter.next(), Some(63));
663 assert_eq!(iter.next(), None);
664
665 }
667
668 #[test]
669 fn non_consuming_iterator() {
670 let bits = BitSet64(0b1101); let mut sum = 0;
673 let mut count = 0;
674
675 for bit in &bits {
677 sum += bit;
678 count += 1;
679 }
680 assert_eq!(3, count);
681 assert_eq!(5, sum);
682
683 let mut sum = 0;
684 let mut count = 0;
685 for bit in &bits {
687 sum += bit;
688 count += 1;
689 }
690 assert_eq!(3, count);
691 assert_eq!(5, sum);
692 }
693
694 #[test]
695 fn non_consuming_iterator2() {
696 let mut bits = BitSet64::new();
697 bits.set(5);
698 bits.set(12);
699
700 let count = bits.iter().count();
702 assert_eq!(count, 2);
703
704 let mut last_val = 0;
706 for bit in &bits {
707 last_val = bit;
708 }
709 assert_eq!(last_val, 12);
710
711 assert!(bits.test(5));
713 }
714
715 #[test]
716 fn from_iterator() {
717 let indices = [1, 3, 5];
718 let bits: BitSet64 = indices.iter().copied().collect();
720
721 assert!(bits.test(1));
722 assert!(bits.test(3));
723 assert!(bits.test(5));
724 assert!(!bits.test(2));
725 }
726
727 #[test]
728 fn empty_and_full() {
729 let empty = BitSet64::new();
730 assert_eq!(empty.iter().count(), 0);
731
732 let mut full = BitSet64::new();
733 full.set_all();
734 assert_eq!(full.iter().count(), 64);
735 }
736}