simple_bitset/
bitset64.rs1use core::fmt;
2use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Index};
3use serde::{Deserialize, Serialize};
4
5#[derive(Clone, Copy, Debug, Ord, PartialOrd, Eq, PartialEq, Deserialize, Serialize)]
8pub struct BitSet64(u64);
9
10impl BitSet64 {
11 pub const fn new() -> Self {
13 Self(0)
14 }
15}
16
17impl Default for BitSet64 {
18 fn default() -> Self {
19 Self::new()
20 }
21}
22
23impl BitSet64 {
24 #[inline]
26 pub fn reset_all(&mut self) {
27 self.0 = 0;
28 }
29
30 #[inline]
32 pub fn reset(&mut self, index: u8) {
33 if index < 64 {
34 self.0 &= !(1u64 << index);
35 }
36 }
37
38 #[inline]
40 pub fn set_all(&mut self) {
41 self.0 = u64::MAX;
42 }
43
44 #[inline]
46 pub fn set(&mut self, index: u8) {
47 if index < 64 {
48 self.0 |= 1u64 << index;
49 }
50 }
51
52 #[inline]
54 pub fn flip(&mut self, index: u8) {
55 if index < 64 {
56 self.0 ^= 1u64 << index;
57 }
58 }
59
60 #[inline]
62 pub fn flip_all(&mut self) {
63 self.0 = !self.0;
64 }
65
66 #[inline]
69 pub fn and_not(&mut self, other: Self) {
70 self.0 &= !other.0;
71 }
72
73 #[inline]
76 pub fn test(&self, index: u8) -> bool {
77 if index < 64 {
78 (self.0 & (1u64 << index)) != 0
79 } else {
80 false
81 }
82 }
83
84 #[inline]
86 pub const fn count_ones(&self) -> u32 {
87 self.0.count_ones()
88 }
89
90 #[inline]
93 pub const fn leading_zeros(&self) -> u32 {
94 self.0.leading_zeros()
95 }
96
97 #[inline]
99 pub const fn is_empty(&self) -> bool {
100 self.0 == 0
101 }
102
103 #[inline]
106 pub const fn last_set(&self) -> Option<u8> {
107 if self.is_empty() {
108 None
109 } else {
110 #[allow(clippy::cast_possible_truncation)]
112 Some(63 - self.0.leading_zeros() as u8)
113 }
114 }
115
116 #[inline]
118 pub const fn is_superset(&self, other: &BitSet64) -> bool {
119 (self.0 & other.0) == other.0
122 }
123
124 #[inline]
126 pub const fn is_subset(&self, other: &BitSet64) -> bool {
127 other.is_superset(self)
128 }
129
130 #[inline]
133 pub const fn intersects(&self, other: &Self) -> bool {
134 self.0 & other.0 != 0
137 }
138
139 #[inline]
141 pub fn iter(&self) -> BitSet64Iter {
142 self.into_iter()
143 }
144}
145
146impl BitOr for BitSet64 {
149 type Output = Self;
150 fn bitor(self, rhs: Self) -> Self::Output {
151 Self(self.0 | rhs.0)
152 }
153}
154
155impl BitAnd for BitSet64 {
156 type Output = Self;
157 fn bitand(self, rhs: Self) -> Self::Output {
158 Self(self.0 & rhs.0)
159 }
160}
161
162impl BitXor for BitSet64 {
163 type Output = Self;
164 fn bitxor(self, rhs: Self) -> Self::Output {
165 Self(self.0 ^ rhs.0)
166 }
167}
168
169impl BitOrAssign for BitSet64 {
170 fn bitor_assign(&mut self, rhs: Self) {
171 self.0 |= rhs.0;
172 }
173}
174
175impl BitAndAssign for BitSet64 {
176 fn bitand_assign(&mut self, rhs: Self) {
177 self.0 &= rhs.0;
178 }
179}
180
181impl BitXorAssign for BitSet64 {
182 fn bitxor_assign(&mut self, rhs: Self) {
183 self.0 ^= rhs.0;
184 }
185}
186
187impl Index<u8> for BitSet64 {
188 type Output = bool;
189
190 fn index(&self, index: u8) -> &Self::Output {
191 if self.test(index) { &true } else { &false }
193 }
194}
195
196impl Index<usize> for BitSet64 {
197 type Output = bool;
198
199 #[allow(clippy::cast_possible_truncation)]
200 fn index(&self, index: usize) -> &Self::Output {
201 if self.test(index as u8) { &true } else { &false }
203 }
204}
205
206impl From<u32> for BitSet64 {
208 #[inline]
209 fn from(a: u32) -> Self {
210 Self(u64::from(a))
211 }
212}
213
214impl From<(u32, u32)> for BitSet64 {
216 #[inline]
217 fn from((a, b): (u32, u32)) -> Self {
218 Self(u64::from(a) << 32 | u64::from(b))
219 }
220}
221
222#[derive(Debug, Default, Eq, PartialEq)]
225pub struct BitSet64Iter(u64);
226
227impl Iterator for BitSet64Iter {
229 type Item = u8;
230
231 fn next(&mut self) -> Option<Self::Item> {
232 if self.0 == 0 {
233 None
234 } else {
235 #[allow(clippy::cast_possible_truncation)]
237 let index = self.0.trailing_zeros() as u8;
238 self.0 &= self.0 - 1;
240 Some(index)
241 }
242 }
243
244 #[inline]
245 fn size_hint(&self) -> (usize, Option<usize>) {
246 let len = self.0.count_ones() as usize;
248 (len, Some(len))
249 }
250}
251
252impl ExactSizeIterator for BitSet64Iter {}
254impl core::iter::FusedIterator for BitSet64Iter {}
255
256impl IntoIterator for &BitSet64 {
258 type Item = u8;
259 type IntoIter = BitSet64Iter;
260
261 fn into_iter(self) -> Self::IntoIter {
262 BitSet64Iter(self.0)
265 }
266}
267
268impl IntoIterator for BitSet64 {
270 type Item = u8;
271 type IntoIter = BitSet64Iter;
272
273 fn into_iter(self) -> Self::IntoIter {
274 BitSet64Iter(self.0)
277 }
278}
279
280impl FromIterator<u8> for BitSet64 {
282 fn from_iter<I: IntoIterator<Item = u8>>(iter: I) -> Self {
283 let mut bitset = Self::new();
284 for index in iter {
285 bitset.set(index);
286 }
287 bitset
288 }
289}
290
291impl Extend<u8> for BitSet64 {
292 fn extend<I: IntoIterator<Item = u8>>(&mut self, iter: I) {
293 for index in iter {
294 self.set(index);
295 }
296 }
297}
298
299impl fmt::Binary for BitSet64 {
302 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
303 if f.alternate() {
305 f.write_str("0b")?;
306 }
307 for i in (0..64).rev() {
309 let val = (self.0 >> i) & 1;
310 write!(f, "{val}")?;
311 }
312
313 Ok(())
314 }
315}
316
317impl fmt::UpperHex for BitSet64 {
318 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
319 if f.alternate() {
320 f.write_str("0x")?;
321 }
322 write!(f, "{:016X}", self.0)
323 }
324}
325
326#[cfg(test)]
327mod tests {
328 use super::*;
329
330 fn is_normal<T: Sized + Send + Sync + Unpin>() {}
331 fn _is_full<T: Sized + Send + Sync + Unpin + Copy + Clone + Default + PartialEq>() {}
332 fn is_config<
333 T: Sized + Send + Sync + Unpin + Copy + Clone + Default + PartialEq + Serialize + for<'a> Deserialize<'a>,
334 >() {
335 }
336
337 #[test]
338 fn normal_types() {
339 is_config::<BitSet64>();
340 is_normal::<BitSet64Iter>();
341 }
342 #[test]
343 fn new() {
344 let mut bits = BitSet64::new();
345 bits.set(42);
346 assert!(bits[42u8]);
347 assert!(bits.test(42));
348 }
349 #[allow(unused)]
350 #[test]
351 fn const_new() {
352 const FLAGS: BitSet64 = BitSet64::new();
353 const EMPTY_CHECK: bool = FLAGS.is_empty(); }
355 #[test]
356 fn assign() {
357 let mut bits = BitSet64::new();
358 bits.set(42);
359 assert!(bits[42u8]);
360 assert!(bits.test(42));
361 let mask = bits;
362 assert!(mask.test(42));
363 }
364 #[test]
365 fn from() {
366 let _bits = BitSet64::from((0xab_u32, 0x12_u32));
367 }
368 #[test]
369 fn flip_all() {
370 let mut bitset = BitSet64::new();
371
372 bitset.set(0);
374 bitset.set(32);
375
376 bitset.flip_all();
377
378 assert!(!bitset.test(0));
380 assert!(!bitset.test(32));
381 assert!(bitset.test(1));
382 assert!(bitset.test(33));
383
384 let mut empty_set = BitSet64::new();
386 empty_set.flip_all(); let mut full_set = BitSet64::new();
389 full_set.set_all();
390
391 assert_eq!(empty_set, full_set);
392
393 empty_set.flip_all(); assert!(empty_set.is_empty());
395 }
396 #[test]
397 fn inplace_logical_ops() {
398 let mut set_a = BitSet64::new();
399 let mut set_b = BitSet64::new();
400
401 set_a.set(10);
403 set_a.set(50);
404
405 set_b.set(10);
406 set_b.set(60);
407
408 let mut result = set_a;
410 result &= set_b;
411 assert!(result.test(10));
412 assert!(!result.test(50));
413 assert!(!result.test(60));
414
415 let mut result = set_a;
417 result |= set_b;
418 assert!(result.test(10));
419 assert!(result.test(50));
420 assert!(result.test(60));
421
422 let mut result = set_a;
424 result ^= set_b;
425 assert!(!result.test(10)); assert!(result.test(50));
427 assert!(result.test(60));
428
429 let mut result = set_a;
431 result.and_not(set_b);
432 assert!(!result.test(10)); assert!(result.test(50)); assert!(!result.test(60)); }
436 #[test]
437 fn exercise() {
438 let mut system_flags = BitSet64::new();
439 let error_mask = BitSet64::new(); system_flags |= error_mask;
443
444 system_flags ^= error_mask;
446
447 system_flags &= BitSet64(0x0000_FFFF_FFFF_FFFF);
449
450 let mut set_a = BitSet64::new();
451 set_a.set(10);
452 set_a.set(20);
453
454 let mut set_b = BitSet64::new();
455 set_b.set(20);
456 set_b.set(30);
457
458 let common = set_a & set_b;
460 assert!(!common.test(10));
461 assert!(common.test(20));
462 assert!(!common.test(30));
463
464 let all = set_a | set_b;
466 assert!(all.test(10));
467 assert!(all.test(20));
468 assert!(all.test(30));
469
470 let diff = set_a ^ set_b;
472 assert!(diff.test(10));
473 assert!(!diff.test(20));
474 assert!(diff.test(30));
475 }
476 #[test]
477 fn iterator_consuming() {
478 let mut bits = BitSet64::new();
479 bits.set(2);
480 bits.set(10);
481
482 let mut sum = 0;
483 let mut count = 0;
484 for bit in &bits {
485 sum += bit;
486 count += 1;
487 }
488 assert_eq!(2, count);
489 assert_eq!(12, sum);
490 }
491 #[test]
492 fn into_iter_consuming() {
493 let mut bits = BitSet64::new();
494 bits.set(0);
495 bits.set(10);
496 bits.set(63);
497
498 let mut iter = bits.into_iter();
500
501 assert_eq!(iter.next(), Some(0));
502 assert_eq!(iter.next(), Some(10));
503 assert_eq!(iter.next(), Some(63));
504 assert_eq!(iter.next(), None);
505
506 }
508
509 #[test]
510 fn non_consuming_iterator() {
511 let bits = BitSet64(0b1101); let mut sum = 0;
514 let mut count = 0;
515
516 for bit in &bits {
518 sum += bit;
519 count += 1;
520 }
521 assert_eq!(3, count);
522 assert_eq!(5, sum);
523
524 let mut sum = 0;
525 let mut count = 0;
526 for bit in &bits {
528 sum += bit;
529 count += 1;
530 }
531 assert_eq!(3, count);
532 assert_eq!(5, sum);
533 }
534
535 #[test]
536 fn non_consuming_iterator2() {
537 let mut bits = BitSet64::new();
538 bits.set(5);
539 bits.set(12);
540
541 let count = bits.iter().count();
543 assert_eq!(count, 2);
544
545 let mut last_val = 0;
547 for bit in &bits {
548 last_val = bit;
549 }
550 assert_eq!(last_val, 12);
551
552 assert!(bits.test(5));
554 }
555
556 #[test]
557 fn from_iterator() {
558 let indices = [1, 3, 5];
559 let bits: BitSet64 = indices.iter().copied().collect();
561
562 assert!(bits.test(1));
563 assert!(bits.test(3));
564 assert!(bits.test(5));
565 assert!(!bits.test(2));
566 }
567
568 #[test]
569 fn empty_and_full() {
570 let empty = BitSet64::new();
571 assert_eq!(empty.iter().count(), 0);
572
573 let mut full = BitSet64::new();
574 full.set_all();
575 assert_eq!(full.iter().count(), 64);
576 }
577}