use crate::traits::{BitRead, BitResize, BitStack, BitWrite};
use std::fmt::Debug;
#[derive(Debug, Hash, PartialEq, Eq)]
pub struct BitList {
store: Vec<usize>,
len: usize,
}
impl BitList {
#[inline]
pub fn new(len: usize) -> Self {
Self {
store: Vec::new(),
len,
}
}
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
Self {
store: Vec::with_capacity(capacity),
len: 0,
}
}
#[inline]
pub fn iter(&self) -> Iter<'_> {
Iter(self.store.iter())
}
#[inline]
pub fn first(&self) -> Option<usize> {
self.store.first().map(|&index| index)
}
#[inline]
pub fn last(&self) -> Option<usize> {
self.store.last().map(|&index| index)
}
pub fn capacity(&self) -> usize {
self.store.capacity()
}
}
impl BitRead for BitList {
type Iter<'a>
= Iter<'a>
where
Self: 'a;
fn len(&self) -> usize {
self.len
}
fn test(&self, idx: usize) -> bool {
self.store.binary_search(&idx).is_ok()
}
fn iter(&self) -> Self::Iter<'_> {
Iter(self.store.iter())
}
}
impl BitWrite for BitList {
fn set(&mut self, index: usize) {
match self.store.binary_search(&index) {
Ok(_) => {}
Err(pos) => self.store.insert(pos, index),
}
}
fn reset(&mut self, index: usize) {
match self.store.binary_search(&index) {
Ok(pos) => {
self.store.remove(pos);
}
Err(_) => {}
}
}
fn flip(&mut self, index: usize) {
match self.store.binary_search(&index) {
Ok(pos) => {
self.store.remove(pos);
}
Err(pos) => self.store.insert(pos, index),
}
}
fn test_and_set(&mut self, index: usize) -> bool {
match self.store.binary_search(&index) {
Ok(_) => true,
Err(pos) => {
self.store.insert(pos, index);
false
}
}
}
fn fill(&mut self) {
for i in 0..self.len {
if i < self.store.len() {
self.store[i] = i;
} else {
self.store.push(i);
}
}
}
fn clear(&mut self) {
self.store.clear();
}
}
impl BitResize for BitList {
fn resize(&mut self, new_len: usize) {
match self.len.cmp(&new_len) {
std::cmp::Ordering::Less => self.len = new_len,
std::cmp::Ordering::Equal => {}
std::cmp::Ordering::Greater => {
while let Some(&index) = self.store.last() {
if index > new_len {
self.store.pop();
} else {
break;
}
}
self.len = new_len;
}
}
}
}
impl BitStack for BitList {
fn push(&mut self, value: bool) {
if value {
self.store.push(self.len);
}
self.len += 1;
}
fn pop(&mut self) -> Option<bool> {
if let Some(&index) = self.store.last() {
self.len -= 1;
if index == self.len {
self.store.pop();
return Some(true);
} else {
return Some(false);
}
}
None
}
}
pub struct Iter<'a>(std::slice::Iter<'a, usize>);
impl<'a> Iterator for Iter<'a> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|&x| x)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_debug() {
let mut bl: BitList = BitList::new(60);
bl.set(1);
bl.set(17);
bl.set(27);
bl.set(47);
assert_eq!(
format!("{bl:?}"),
"BitList { store: [1, 17, 27, 47], len: 60 }"
);
}
#[test]
fn test_new_and_len() {
let bl: BitList = BitList::new(10);
assert_eq!(bl.len(), 10);
assert!(bl.none());
let bl0: BitList = BitList::new(0);
assert_eq!(bl0.len(), 0);
assert!(bl0.is_empty());
let mut iter = bl.iter();
assert!(iter.next().is_none());
}
#[test]
fn test_set_and_test() {
let mut bl: BitList = BitList::new(8);
for i in 0..8 {
assert!(!bl.test(i));
bl.set(i);
assert!(bl.test(i));
}
}
#[test]
fn test_reset() {
let mut bl: BitList = BitList::new(8);
for i in 0..8 {
bl.set(i);
}
for i in 0..8 {
bl.reset(i);
assert!(!bl.test(i));
}
}
#[test]
fn test_test_and_set() {
let mut bl: BitList = BitList::new(4);
assert!(!bl.test_and_set(2));
assert!(bl.test_and_set(2));
assert!(bl.test(2));
}
#[test]
fn test_fill_and_clear() {
let mut bl: BitList = BitList::new(10);
bl.fill();
for i in 0..10 {
assert!(bl.test(i));
}
bl.clear();
assert!(bl.none());
}
#[test]
fn test_count_ones() {
let mut bl: BitList = BitList::new(16);
assert_eq!(bl.count_ones(), 0);
bl.set(0);
bl.set(3);
bl.set(15);
assert_eq!(bl.count_ones(), 3);
bl.fill();
assert_eq!(bl.count_ones(), 16);
bl.clear();
assert_eq!(bl.count_ones(), 0);
}
#[test]
fn test_all_and_any() {
let mut bl: BitList = BitList::new(5);
assert!(!bl.all());
assert!(!bl.any());
bl.set(0);
assert!(!bl.all());
assert!(bl.any());
bl.fill();
assert!(bl.all());
bl.reset(2);
assert!(!bl.all());
assert!(bl.any());
bl.clear();
assert!(!bl.any());
}
#[test]
fn test_resize_grow_and_shrink() {
let mut bl: BitList = BitList::new(4);
bl.set(1);
bl.resize(8);
assert!(bl.test(1));
bl.set(7);
assert!(bl.test(7));
bl.resize(2);
assert_eq!(bl.len(), 2);
assert!(bl.test(1));
}
#[test]
fn test_first() {
let mut bl: BitList = BitList::new(0);
assert_eq!(bl.first(), None);
bl.set(5);
assert_eq!(bl.first(), Some(5));
bl.set(2); assert_eq!(bl.first(), Some(2));
let mut bl2: BitList = BitList::new(10);
bl2.set(5);
bl2.set(2);
assert_eq!(bl2.first(), Some(2)); }
#[test]
fn test_flip() {
let mut bl: BitList = BitList::new(8);
for i in 0..4 {
assert!(!bl.test(i));
bl.flip(i);
assert!(bl.test(i));
}
for i in 0..4 {
assert!(bl.test(i));
bl.flip(i);
assert!(!bl.test(i));
}
}
#[test]
fn test_bit_stack_trait() {
let mut bit_stack = BitList::new(0);
use crate::traits::BitStack;
<BitList as BitStack>::push(&mut bit_stack, true);
<BitList as BitStack>::push(&mut bit_stack, false);
<BitList as BitStack>::push(&mut bit_stack, true);
assert_eq!(bit_stack.len(), 3);
assert!(bit_stack.test(0));
assert!(!bit_stack.test(1));
assert!(bit_stack.test(2));
assert_eq!(<BitList as BitStack>::pop(&mut bit_stack), Some(true));
assert_eq!(bit_stack.len(), 2);
assert_eq!(<BitList as BitStack>::pop(&mut bit_stack), Some(false));
assert_eq!(bit_stack.len(), 1);
assert_eq!(<BitList as BitStack>::pop(&mut bit_stack), Some(true));
assert_eq!(bit_stack.len(), 0);
assert_eq!(<BitList as BitStack>::pop(&mut bit_stack), None);
}
#[test]
fn test_out_of_bounds() {
let mut bl: BitList = BitList::new(10);
bl.set(9);
assert!(bl.test(9));
bl.set(10); assert!(bl.test(10));
bl.set(20);
assert!(bl.test(20));
bl.resize(10);
assert!(bl.test(9));
}
}