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 #[inline]
96 #[must_use]
97 pub const fn count_ones(&self) -> u32 {
98 self.0.count_ones()
99 }
100
101 #[inline]
104 #[must_use]
105 pub const fn leading_zeros(&self) -> u32 {
106 self.0.leading_zeros()
107 }
108
109 #[inline]
111 #[must_use]
112 pub const fn is_empty(&self) -> bool {
113 self.0 == 0
114 }
115
116 #[inline]
119 #[must_use]
120 pub const fn last_set(&self) -> Option<u8> {
121 if self.is_empty() {
122 None
123 } else {
124 #[allow(clippy::cast_possible_truncation)]
126 Some(63 - self.0.leading_zeros() as u8)
127 }
128 }
129
130 #[inline]
132 #[must_use]
133 pub const fn is_superset(&self, other: BitSet64) -> bool {
134 (self.0 & other.0) == other.0
137 }
138
139 #[inline]
141 #[must_use]
142 pub const fn is_subset(&self, other: BitSet64) -> bool {
143 other.is_superset(*self)
144 }
145
146 #[inline]
149 #[must_use]
150 pub const fn intersects(&self, other: Self) -> bool {
151 self.0 & other.0 != 0
154 }
155
156 #[inline]
158 #[must_use]
159 pub fn iter(&self) -> BitSet64Iter {
160 self.into_iter()
161 }
162}
163
164impl BitOr for BitSet64 {
167 type Output = Self;
168 fn bitor(self, other: Self) -> Self::Output {
169 Self(self.0 | other.0)
170 }
171}
172
173impl BitAnd for BitSet64 {
174 type Output = Self;
175 fn bitand(self, other: Self) -> Self::Output {
176 Self(self.0 & other.0)
177 }
178}
179
180impl BitXor for BitSet64 {
181 type Output = Self;
182 fn bitxor(self, other: Self) -> Self::Output {
183 Self(self.0 ^ other.0)
184 }
185}
186
187impl BitOrAssign for BitSet64 {
188 fn bitor_assign(&mut self, other: Self) {
189 self.0 |= other.0;
190 }
191}
192
193impl BitAndAssign for BitSet64 {
194 fn bitand_assign(&mut self, other: Self) {
195 self.0 &= other.0;
196 }
197}
198
199impl BitXorAssign for BitSet64 {
200 fn bitxor_assign(&mut self, other: Self) {
201 self.0 ^= other.0;
202 }
203}
204
205impl Index<u8> for BitSet64 {
206 type Output = bool;
207
208 fn index(&self, index: u8) -> &Self::Output {
209 if self.test(index) { &true } else { &false }
211 }
212}
213
214impl Index<usize> for BitSet64 {
215 type Output = bool;
216
217 #[allow(clippy::cast_possible_truncation)]
218 fn index(&self, index: usize) -> &Self::Output {
219 if self.test(index as u8) { &true } else { &false }
221 }
222}
223
224impl From<u32> for BitSet64 {
226 #[inline]
227 fn from(a: u32) -> Self {
228 Self(u64::from(a))
229 }
230}
231
232impl From<(u32, u32)> for BitSet64 {
234 #[inline]
235 fn from((a, b): (u32, u32)) -> Self {
236 Self(u64::from(a) << 32 | u64::from(b))
237 }
238}
239
240#[derive(Debug, Default, Eq, PartialEq)]
244pub struct BitSet64Iter(u64);
245
246impl Iterator for BitSet64Iter {
248 type Item = u8;
249
250 fn next(&mut self) -> Option<Self::Item> {
251 if self.0 == 0 {
252 None
253 } else {
254 #[allow(clippy::cast_possible_truncation)]
256 let index = self.0.trailing_zeros() as u8;
257 self.0 &= self.0 - 1;
259 Some(index)
260 }
261 }
262
263 #[inline]
264 fn size_hint(&self) -> (usize, Option<usize>) {
265 let len = self.0.count_ones() as usize;
267 (len, Some(len))
268 }
269}
270
271impl ExactSizeIterator for BitSet64Iter {}
273impl core::iter::FusedIterator for BitSet64Iter {}
274
275impl IntoIterator for &BitSet64 {
277 type Item = u8;
278 type IntoIter = BitSet64Iter;
279
280 fn into_iter(self) -> Self::IntoIter {
281 BitSet64Iter(self.0)
284 }
285}
286
287impl IntoIterator for BitSet64 {
289 type Item = u8;
290 type IntoIter = BitSet64Iter;
291
292 fn into_iter(self) -> Self::IntoIter {
293 BitSet64Iter(self.0)
296 }
297}
298
299impl FromIterator<u8> for BitSet64 {
301 fn from_iter<I: IntoIterator<Item = u8>>(iter: I) -> Self {
302 let mut bitset = Self::new();
303 for index in iter {
304 bitset.set(index);
305 }
306 bitset
307 }
308}
309
310impl Extend<u8> for BitSet64 {
311 fn extend<I: IntoIterator<Item = u8>>(&mut self, iter: I) {
312 for index in iter {
313 self.set(index);
314 }
315 }
316}
317
318impl fmt::Binary for BitSet64 {
321 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
322 if f.alternate() {
324 f.write_str("0b")?;
325 }
326 for i in (0..64).rev() {
328 let val = (self.0 >> i) & 1;
329 write!(f, "{val}")?;
330 }
331
332 Ok(())
333 }
334}
335
336impl fmt::UpperHex for BitSet64 {
337 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
338 if f.alternate() {
339 f.write_str("0x")?;
340 }
341 write!(f, "{:016X}", self.0)
342 }
343}
344
345#[cfg(test)]
346mod tests {
347 use super::*;
348
349 fn is_normal<T: Sized + Send + Sync + Unpin>() {}
350 fn is_full<T: Sized + Send + Sync + Unpin + Copy + Clone + Default + PartialEq>() {}
351 #[cfg(feature = "serde")]
352 fn is_config<T: Serialize + for<'a> Deserialize<'a>>() {}
353
354 #[test]
355 fn normal_types() {
356 is_full::<BitSet64>();
357 #[cfg(feature = "serde")]
358 is_config::<BitSet64>();
359 is_normal::<BitSet64Iter>();
360 }
361
362 #[test]
363 fn new() {
364 let mut bits = BitSet64::new();
365 bits.set(42);
366 assert!(bits[42u8]);
367 assert!(bits.test(42));
368 }
369
370 #[test]
371 fn const_new() {
372 const FLAGS: BitSet64 = BitSet64::new();
373 const EMPTY_CHECK: bool = FLAGS.is_empty(); assert_eq!(0, FLAGS.0);
375 #[allow(clippy::assertions_on_constants)]
376 {
377 assert!(EMPTY_CHECK);
378 }
379 }
380
381 #[test]
382 fn assign() {
383 let mut bits = BitSet64::new();
384 bits.set(42);
385 assert!(bits[42u8]);
386 assert!(bits.test(42));
387 let mask = bits;
388 assert!(mask.test(42));
389 }
390
391 #[test]
392 fn from() {
393 let _bits = BitSet64::from((0xab_u32, 0x12_u32));
394 }
395
396 #[test]
397 fn flip_all() {
398 let mut bitset = BitSet64::new();
399
400 bitset.set(0);
402 bitset.set(32);
403
404 bitset.flip_all();
405
406 assert!(!bitset.test(0));
408 assert!(!bitset.test(32));
409 assert!(bitset.test(1));
410 assert!(bitset.test(33));
411
412 let mut empty_set = BitSet64::new();
414 empty_set.flip_all(); let mut full_set = BitSet64::new();
417 full_set.set_all();
418
419 assert_eq!(empty_set, full_set);
420
421 empty_set.flip_all(); assert!(empty_set.is_empty());
423 }
424
425 #[test]
426 fn leading_zeros() {
427 let mut bitset = BitSet64::new();
428
429 assert_eq!(bitset.leading_zeros(), 64);
431
432 bitset.set(63);
434 assert_eq!(bitset.leading_zeros(), 0);
435
436 bitset.reset_all();
438 bitset.set(62);
439 assert_eq!(bitset.leading_zeros(), 1);
440 }
441
442 #[test]
443 fn last_set() {
444 let mut bitset = BitSet64::new();
445
446 assert_eq!(bitset.last_set(), None);
448
449 bitset.set(0);
451 assert_eq!(bitset.last_set(), Some(0));
452
453 bitset.set(10);
455 bitset.set(45);
456 assert_eq!(bitset.last_set(), Some(45));
457
458 bitset.reset_all();
460 bitset.set(63);
461 assert_eq!(bitset.last_set(), Some(63));
462 }
463
464 #[test]
465 fn is_superset() {
466 let mut set_a = BitSet64::new();
467 let mut set_b = BitSet64::new();
468
469 assert!(set_a.is_superset(set_b));
471
472 set_a.set(10);
474 set_a.set(60);
475
476 set_b.set(10);
477
478 assert!(set_a.is_superset(set_b));
480 assert!(!set_b.is_superset(set_a));
482
483 set_b.set(60);
485 assert!(set_a.is_superset(set_b));
486
487 let mut set_c = BitSet64::new();
489 let mut set_d = BitSet64::new();
490 set_c.set(15); set_d.set(15);
493 set_d.set(55); assert!(!set_c.is_superset(set_d));
498 }
499
500 #[test]
501 fn intersects() {
502 let mut set_a = BitSet64::new();
503 let mut set_b = BitSet64::new();
504
505 assert!(!set_a.intersects(set_b));
507
508 set_a.set(15);
510 assert!(!set_a.intersects(set_b));
511
512 set_b.set(15);
514 assert!(set_a.intersects(set_b));
515 assert!(set_b.intersects(set_a));
516
517 set_a.reset_all();
519 set_b.reset_all();
520 set_a.set(10);
521 set_b.set(60);
522 assert!(!set_a.intersects(set_b));
523
524 set_a.set(60);
526 assert!(set_a.intersects(set_b));
527 }
528
529 #[test]
530 fn inplace_logical_ops() {
531 let mut set_a = BitSet64::new();
532 let mut set_b = BitSet64::new();
533
534 set_a.set(10);
536 set_a.set(50);
537
538 set_b.set(10);
539 set_b.set(60);
540
541 let mut result = set_a;
543 result &= set_b;
544 assert!(result.test(10));
545 assert!(!result.test(50));
546 assert!(!result.test(60));
547
548 let mut result = set_a;
550 result |= set_b;
551 assert!(result.test(10));
552 assert!(result.test(50));
553 assert!(result.test(60));
554
555 let mut result = set_a;
557 result ^= set_b;
558 assert!(!result.test(10)); assert!(result.test(50));
560 assert!(result.test(60));
561
562 let mut result = set_a;
564 result.and_not(set_b);
565 assert!(!result.test(10)); assert!(result.test(50)); assert!(!result.test(60)); }
569
570 #[test]
571 fn exercise() {
572 let mut system_flags = BitSet64::new();
573 let error_mask = BitSet64::new(); system_flags |= error_mask;
577
578 system_flags ^= error_mask;
580
581 system_flags &= BitSet64(0x0000_FFFF_FFFF_FFFF);
583
584 let mut set_a = BitSet64::new();
585 set_a.set(10);
586 set_a.set(20);
587
588 let mut set_b = BitSet64::new();
589 set_b.set(20);
590 set_b.set(30);
591
592 let common = set_a & set_b;
594 assert!(!common.test(10));
595 assert!(common.test(20));
596 assert!(!common.test(30));
597
598 let all = set_a | set_b;
600 assert!(all.test(10));
601 assert!(all.test(20));
602 assert!(all.test(30));
603
604 let diff = set_a ^ set_b;
606 assert!(diff.test(10));
607 assert!(!diff.test(20));
608 assert!(diff.test(30));
609 }
610
611 #[test]
612 fn iterator_consuming() {
613 let mut bits = BitSet64::new();
614 bits.set(2);
615 bits.set(10);
616
617 let mut sum = 0;
618 let mut count = 0;
619 for bit in &bits {
620 sum += bit;
621 count += 1;
622 }
623 assert_eq!(2, count);
624 assert_eq!(12, sum);
625 }
626
627 #[test]
628 fn into_iter_consuming() {
629 let mut bits = BitSet64::new();
630 bits.set(0);
631 bits.set(10);
632 bits.set(63);
633
634 let mut iter = bits.into_iter();
636
637 assert_eq!(iter.next(), Some(0));
638 assert_eq!(iter.next(), Some(10));
639 assert_eq!(iter.next(), Some(63));
640 assert_eq!(iter.next(), None);
641
642 }
644
645 #[test]
646 fn non_consuming_iterator() {
647 let bits = BitSet64(0b1101); let mut sum = 0;
650 let mut count = 0;
651
652 for bit in &bits {
654 sum += bit;
655 count += 1;
656 }
657 assert_eq!(3, count);
658 assert_eq!(5, sum);
659
660 let mut sum = 0;
661 let mut count = 0;
662 for bit in &bits {
664 sum += bit;
665 count += 1;
666 }
667 assert_eq!(3, count);
668 assert_eq!(5, sum);
669 }
670
671 #[test]
672 fn non_consuming_iterator2() {
673 let mut bits = BitSet64::new();
674 bits.set(5);
675 bits.set(12);
676
677 let count = bits.iter().count();
679 assert_eq!(count, 2);
680
681 let mut last_val = 0;
683 for bit in &bits {
684 last_val = bit;
685 }
686 assert_eq!(last_val, 12);
687
688 assert!(bits.test(5));
690 }
691
692 #[test]
693 fn from_iterator() {
694 let indices = [1, 3, 5];
695 let bits: BitSet64 = indices.iter().copied().collect();
697
698 assert!(bits.test(1));
699 assert!(bits.test(3));
700 assert!(bits.test(5));
701 assert!(!bits.test(2));
702 }
703
704 #[test]
705 fn empty_and_full() {
706 let empty = BitSet64::new();
707 assert_eq!(empty.iter().count(), 0);
708
709 let mut full = BitSet64::new();
710 full.set_all();
711 assert_eq!(full.iter().count(), 64);
712 }
713}