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 pub const fn new() -> Self {
18 Self(0)
19 }
20}
21
22#[cfg(feature = "serde")]
23impl PostcardValue<'_> for BitSet64 {}
24
25impl Default for BitSet64 {
26 fn default() -> Self {
27 Self::new()
28 }
29}
30
31impl BitSet64 {
32 #[inline]
34 pub fn reset_all(&mut self) {
35 self.0 = 0;
36 }
37
38 #[inline]
40 pub fn reset(&mut self, index: u8) {
41 if index < 64 {
42 self.0 &= !(1u64 << index);
43 }
44 }
45
46 #[inline]
48 pub fn set_all(&mut self) {
49 self.0 = u64::MAX;
50 }
51
52 #[inline]
54 pub fn set(&mut self, index: u8) {
55 if index < 64 {
56 self.0 |= 1u64 << index;
57 }
58 }
59
60 #[inline]
62 pub fn flip(&mut self, index: u8) {
63 if index < 64 {
64 self.0 ^= 1u64 << index;
65 }
66 }
67
68 #[inline]
70 pub fn flip_all(&mut self) {
71 self.0 = !self.0;
72 }
73
74 #[inline]
77 pub fn and_not(&mut self, other: Self) {
78 self.0 &= !other.0;
79 }
80
81 #[inline]
84 pub fn test(&self, index: u8) -> bool {
85 if index < 64 {
86 (self.0 & (1u64 << index)) != 0
87 } else {
88 false
89 }
90 }
91
92 #[inline]
94 pub const fn count_ones(&self) -> u32 {
95 self.0.count_ones()
96 }
97
98 #[inline]
101 pub const fn leading_zeros(&self) -> u32 {
102 self.0.leading_zeros()
103 }
104
105 #[inline]
107 pub const fn is_empty(&self) -> bool {
108 self.0 == 0
109 }
110
111 #[inline]
114 pub const fn last_set(&self) -> Option<u8> {
115 if self.is_empty() {
116 None
117 } else {
118 #[allow(clippy::cast_possible_truncation)]
120 Some(63 - self.0.leading_zeros() as u8)
121 }
122 }
123
124 #[inline]
126 pub const fn is_superset(&self, other: &BitSet64) -> bool {
127 (self.0 & other.0) == other.0
130 }
131
132 #[inline]
134 pub const fn is_subset(&self, other: &BitSet64) -> bool {
135 other.is_superset(self)
136 }
137
138 #[inline]
141 pub const fn intersects(&self, other: &Self) -> bool {
142 self.0 & other.0 != 0
145 }
146
147 #[inline]
149 pub fn iter(&self) -> BitSet64Iter {
150 self.into_iter()
151 }
152}
153
154impl BitOr for BitSet64 {
157 type Output = Self;
158 fn bitor(self, rhs: Self) -> Self::Output {
159 Self(self.0 | rhs.0)
160 }
161}
162
163impl BitAnd for BitSet64 {
164 type Output = Self;
165 fn bitand(self, rhs: Self) -> Self::Output {
166 Self(self.0 & rhs.0)
167 }
168}
169
170impl BitXor for BitSet64 {
171 type Output = Self;
172 fn bitxor(self, rhs: Self) -> Self::Output {
173 Self(self.0 ^ rhs.0)
174 }
175}
176
177impl BitOrAssign for BitSet64 {
178 fn bitor_assign(&mut self, rhs: Self) {
179 self.0 |= rhs.0;
180 }
181}
182
183impl BitAndAssign for BitSet64 {
184 fn bitand_assign(&mut self, rhs: Self) {
185 self.0 &= rhs.0;
186 }
187}
188
189impl BitXorAssign for BitSet64 {
190 fn bitxor_assign(&mut self, rhs: Self) {
191 self.0 ^= rhs.0;
192 }
193}
194
195impl Index<u8> for BitSet64 {
196 type Output = bool;
197
198 fn index(&self, index: u8) -> &Self::Output {
199 if self.test(index) { &true } else { &false }
201 }
202}
203
204impl Index<usize> for BitSet64 {
205 type Output = bool;
206
207 #[allow(clippy::cast_possible_truncation)]
208 fn index(&self, index: usize) -> &Self::Output {
209 if self.test(index as u8) { &true } else { &false }
211 }
212}
213
214impl From<u32> for BitSet64 {
216 #[inline]
217 fn from(a: u32) -> Self {
218 Self(u64::from(a))
219 }
220}
221
222impl From<(u32, u32)> for BitSet64 {
224 #[inline]
225 fn from((a, b): (u32, u32)) -> Self {
226 Self(u64::from(a) << 32 | u64::from(b))
227 }
228}
229
230#[derive(Debug, Default, Eq, PartialEq)]
233pub struct BitSet64Iter(u64);
234
235impl Iterator for BitSet64Iter {
237 type Item = u8;
238
239 fn next(&mut self) -> Option<Self::Item> {
240 if self.0 == 0 {
241 None
242 } else {
243 #[allow(clippy::cast_possible_truncation)]
245 let index = self.0.trailing_zeros() as u8;
246 self.0 &= self.0 - 1;
248 Some(index)
249 }
250 }
251
252 #[inline]
253 fn size_hint(&self) -> (usize, Option<usize>) {
254 let len = self.0.count_ones() as usize;
256 (len, Some(len))
257 }
258}
259
260impl ExactSizeIterator for BitSet64Iter {}
262impl core::iter::FusedIterator for BitSet64Iter {}
263
264impl IntoIterator for &BitSet64 {
266 type Item = u8;
267 type IntoIter = BitSet64Iter;
268
269 fn into_iter(self) -> Self::IntoIter {
270 BitSet64Iter(self.0)
273 }
274}
275
276impl IntoIterator for BitSet64 {
278 type Item = u8;
279 type IntoIter = BitSet64Iter;
280
281 fn into_iter(self) -> Self::IntoIter {
282 BitSet64Iter(self.0)
285 }
286}
287
288impl FromIterator<u8> for BitSet64 {
290 fn from_iter<I: IntoIterator<Item = u8>>(iter: I) -> Self {
291 let mut bitset = Self::new();
292 for index in iter {
293 bitset.set(index);
294 }
295 bitset
296 }
297}
298
299impl Extend<u8> for BitSet64 {
300 fn extend<I: IntoIterator<Item = u8>>(&mut self, iter: I) {
301 for index in iter {
302 self.set(index);
303 }
304 }
305}
306
307impl fmt::Binary for BitSet64 {
310 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
311 if f.alternate() {
313 f.write_str("0b")?;
314 }
315 for i in (0..64).rev() {
317 let val = (self.0 >> i) & 1;
318 write!(f, "{val}")?;
319 }
320
321 Ok(())
322 }
323}
324
325impl fmt::UpperHex for BitSet64 {
326 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
327 if f.alternate() {
328 f.write_str("0x")?;
329 }
330 write!(f, "{:016X}", self.0)
331 }
332}
333
334#[cfg(test)]
335mod tests {
336 use super::*;
337
338 fn is_normal<T: Sized + Send + Sync + Unpin>() {}
339 fn _is_full<T: Sized + Send + Sync + Unpin + Copy + Clone + Default + PartialEq>() {}
340 #[cfg(feature = "serde")]
341 fn is_config<T: Serialize + for<'a> Deserialize<'a>>() {}
342
343 #[test]
344 fn normal_types() {
345 is_normal::<BitSet64>();
346 #[cfg(feature = "serde")]
347 is_config::<BitSet64>();
348 is_normal::<BitSet64Iter>();
349 }
350 #[test]
351 fn new() {
352 let mut bits = BitSet64::new();
353 bits.set(42);
354 assert!(bits[42u8]);
355 assert!(bits.test(42));
356 }
357 #[allow(unused)]
358 #[test]
359 fn const_new() {
360 const FLAGS: BitSet64 = BitSet64::new();
361 const EMPTY_CHECK: bool = FLAGS.is_empty(); }
363 #[test]
364 fn assign() {
365 let mut bits = BitSet64::new();
366 bits.set(42);
367 assert!(bits[42u8]);
368 assert!(bits.test(42));
369 let mask = bits;
370 assert!(mask.test(42));
371 }
372 #[test]
373 fn from() {
374 let _bits = BitSet64::from((0xab_u32, 0x12_u32));
375 }
376 #[test]
377 fn flip_all() {
378 let mut bitset = BitSet64::new();
379
380 bitset.set(0);
382 bitset.set(32);
383
384 bitset.flip_all();
385
386 assert!(!bitset.test(0));
388 assert!(!bitset.test(32));
389 assert!(bitset.test(1));
390 assert!(bitset.test(33));
391
392 let mut empty_set = BitSet64::new();
394 empty_set.flip_all(); let mut full_set = BitSet64::new();
397 full_set.set_all();
398
399 assert_eq!(empty_set, full_set);
400
401 empty_set.flip_all(); assert!(empty_set.is_empty());
403 }
404 #[test]
405 fn inplace_logical_ops() {
406 let mut set_a = BitSet64::new();
407 let mut set_b = BitSet64::new();
408
409 set_a.set(10);
411 set_a.set(50);
412
413 set_b.set(10);
414 set_b.set(60);
415
416 let mut result = set_a;
418 result &= set_b;
419 assert!(result.test(10));
420 assert!(!result.test(50));
421 assert!(!result.test(60));
422
423 let mut result = set_a;
425 result |= set_b;
426 assert!(result.test(10));
427 assert!(result.test(50));
428 assert!(result.test(60));
429
430 let mut result = set_a;
432 result ^= set_b;
433 assert!(!result.test(10)); assert!(result.test(50));
435 assert!(result.test(60));
436
437 let mut result = set_a;
439 result.and_not(set_b);
440 assert!(!result.test(10)); assert!(result.test(50)); assert!(!result.test(60)); }
444 #[test]
445 fn exercise() {
446 let mut system_flags = BitSet64::new();
447 let error_mask = BitSet64::new(); system_flags |= error_mask;
451
452 system_flags ^= error_mask;
454
455 system_flags &= BitSet64(0x0000_FFFF_FFFF_FFFF);
457
458 let mut set_a = BitSet64::new();
459 set_a.set(10);
460 set_a.set(20);
461
462 let mut set_b = BitSet64::new();
463 set_b.set(20);
464 set_b.set(30);
465
466 let common = set_a & set_b;
468 assert!(!common.test(10));
469 assert!(common.test(20));
470 assert!(!common.test(30));
471
472 let all = set_a | set_b;
474 assert!(all.test(10));
475 assert!(all.test(20));
476 assert!(all.test(30));
477
478 let diff = set_a ^ set_b;
480 assert!(diff.test(10));
481 assert!(!diff.test(20));
482 assert!(diff.test(30));
483 }
484 #[test]
485 fn iterator_consuming() {
486 let mut bits = BitSet64::new();
487 bits.set(2);
488 bits.set(10);
489
490 let mut sum = 0;
491 let mut count = 0;
492 for bit in &bits {
493 sum += bit;
494 count += 1;
495 }
496 assert_eq!(2, count);
497 assert_eq!(12, sum);
498 }
499 #[test]
500 fn into_iter_consuming() {
501 let mut bits = BitSet64::new();
502 bits.set(0);
503 bits.set(10);
504 bits.set(63);
505
506 let mut iter = bits.into_iter();
508
509 assert_eq!(iter.next(), Some(0));
510 assert_eq!(iter.next(), Some(10));
511 assert_eq!(iter.next(), Some(63));
512 assert_eq!(iter.next(), None);
513
514 }
516
517 #[test]
518 fn non_consuming_iterator() {
519 let bits = BitSet64(0b1101); let mut sum = 0;
522 let mut count = 0;
523
524 for bit in &bits {
526 sum += bit;
527 count += 1;
528 }
529 assert_eq!(3, count);
530 assert_eq!(5, sum);
531
532 let mut sum = 0;
533 let mut count = 0;
534 for bit in &bits {
536 sum += bit;
537 count += 1;
538 }
539 assert_eq!(3, count);
540 assert_eq!(5, sum);
541 }
542
543 #[test]
544 fn non_consuming_iterator2() {
545 let mut bits = BitSet64::new();
546 bits.set(5);
547 bits.set(12);
548
549 let count = bits.iter().count();
551 assert_eq!(count, 2);
552
553 let mut last_val = 0;
555 for bit in &bits {
556 last_val = bit;
557 }
558 assert_eq!(last_val, 12);
559
560 assert!(bits.test(5));
562 }
563
564 #[test]
565 fn from_iterator() {
566 let indices = [1, 3, 5];
567 let bits: BitSet64 = indices.iter().copied().collect();
569
570 assert!(bits.test(1));
571 assert!(bits.test(3));
572 assert!(bits.test(5));
573 assert!(!bits.test(2));
574 }
575
576 #[test]
577 fn empty_and_full() {
578 let empty = BitSet64::new();
579 assert_eq!(empty.iter().count(), 0);
580
581 let mut full = BitSet64::new();
582 full.set_all();
583 assert_eq!(full.iter().count(), 64);
584 }
585}