#[derive(Default, Clone, Copy, PartialEq, Eq, Debug)]
pub struct ActionBitSet {
bits: u64,
}
impl ActionBitSet {
#[inline]
pub fn new() -> Self {
Self { bits: 0 }
}
#[inline]
pub fn insert(&mut self, idx: usize) -> bool {
debug_assert!(idx < 64, "Bit index must be < 64, got {}", idx);
let mask = 1u64 << idx;
let was_present = (self.bits & mask) != 0;
self.bits |= mask;
!was_present
}
#[inline]
pub fn contains(&self, idx: usize) -> bool {
debug_assert!(idx < 64, "Bit index must be < 64, got {}", idx);
(self.bits & (1u64 << idx)) != 0
}
#[inline]
#[allow(dead_code)]
pub fn count(&self) -> usize {
self.bits.count_ones() as usize
}
#[inline]
#[allow(dead_code)]
pub fn is_empty(&self) -> bool {
self.bits == 0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_is_empty() {
let set = ActionBitSet::new();
assert!(set.is_empty());
assert_eq!(set.count(), 0);
}
#[test]
fn test_insert_and_contains() {
let mut set = ActionBitSet::new();
assert!(set.insert(0));
assert!(set.insert(51));
assert!(set.insert(25));
assert!(!set.insert(0));
assert!(!set.insert(51));
assert!(set.contains(0));
assert!(set.contains(25));
assert!(set.contains(51));
assert!(!set.contains(1));
assert!(!set.contains(50));
}
#[test]
fn test_count() {
let mut set = ActionBitSet::new();
assert_eq!(set.count(), 0);
set.insert(0);
assert_eq!(set.count(), 1);
set.insert(10);
assert_eq!(set.count(), 2);
set.insert(10); assert_eq!(set.count(), 2);
set.insert(51);
assert_eq!(set.count(), 3);
}
#[test]
fn test_all_indices() {
let mut set = ActionBitSet::new();
for i in 0..52 {
assert!(set.insert(i));
}
assert_eq!(set.count(), 52);
for i in 0..52 {
assert!(set.contains(i));
}
}
#[test]
fn test_clone_copy() {
let mut set = ActionBitSet::new();
set.insert(10);
set.insert(20);
let copy = set;
assert!(copy.contains(10));
assert!(copy.contains(20));
assert_eq!(copy.count(), 2);
}
}