#![allow(clippy::len_without_is_empty)]
use super::{
Bits256,
Index256,
};
#[derive(Debug)]
pub struct BitRefMut<'a> {
bits: &'a mut Bits256,
at: u8,
}
impl<'a> PartialEq for BitRefMut<'a> {
fn eq(&self, other: &Self) -> bool {
self.get() == other.get()
}
}
impl<'a> Eq for BitRefMut<'a> {}
impl<'a> BitRefMut<'a> {
pub(super) fn new(bits: &'a mut Bits256, at: Index256) -> Self {
Self { bits, at }
}
pub fn get(&self) -> bool {
self.bits.get(self.at)
}
pub fn set_to(&mut self, new_value: bool) {
self.bits.set_to(self.at, new_value)
}
pub fn set(&mut self) {
self.bits.set(self.at)
}
pub fn reset(&mut self) {
self.bits.reset(self.at)
}
pub fn flip(&mut self) {
self.bits.flip(self.at)
}
pub fn xor(&mut self, rhs: bool) {
self.bits.xor(self.at, rhs)
}
pub fn and(&mut self, rhs: bool) {
self.bits.and(self.at, rhs)
}
pub fn or(&mut self, rhs: bool) {
self.bits.or(self.at, rhs)
}
}
#[cfg(test)]
mod tests {
use super::BitRefMut;
use crate::collections::bitvec::Bits256;
fn is_populated_bit_set(index: u8) -> bool {
(index % 5) == 0 || (index % 13) == 0
}
fn populated_bits256() -> Bits256 {
let mut bits256 = Bits256::default();
for i in 0..256 {
let i = i as u8;
bits256.set_to(i, is_populated_bit_set(i));
}
bits256
}
#[test]
fn get_set_works() {
let mut bits256 = populated_bits256();
for i in 0..=255 {
let mut bitref = BitRefMut::new(&mut bits256, i);
let expected = is_populated_bit_set(i);
assert_eq!(bitref.get(), expected);
bitref.set_to(i % 2 == 0);
}
for i in 0..=255 {
assert_eq!(bits256.get(i), i % 2 == 0);
}
}
#[test]
fn flip_works() {
let mut bits256 = populated_bits256();
for i in 0..=255 {
let mut bitref = BitRefMut::new(&mut bits256, i);
bitref.flip();
}
for i in 0..=255 {
assert_eq!(bits256.get(i), !is_populated_bit_set(i));
}
}
#[test]
fn set_and_reset_works() {
let mut bits256 = populated_bits256();
for i in 0..=255 {
let mut bitref = BitRefMut::new(&mut bits256, i);
if i % 2 == 0 {
bitref.set();
} else {
bitref.reset();
}
}
for i in 0..=255 {
assert_eq!(bits256.get(i), i % 2 == 0);
}
}
#[test]
fn bitops_works() {
let mut bits256 = populated_bits256();
for i in 0..=255 {
let mut bitref = BitRefMut::new(&mut bits256, i);
let expected = is_populated_bit_set(i);
fn test_xor(bitref: &mut BitRefMut, expected: bool) {
fn test_xor_for(bitref: &mut BitRefMut, expected: bool, input: bool) {
assert_eq!(bitref.get(), expected);
bitref.xor(input);
assert_eq!(bitref.get(), expected ^ input);
bitref.set_to(expected);
}
test_xor_for(bitref, expected, false);
test_xor_for(bitref, expected, true);
}
test_xor(&mut bitref, expected);
fn test_and(bitref: &mut BitRefMut, expected: bool) {
fn test_and_for(bitref: &mut BitRefMut, expected: bool, input: bool) {
assert_eq!(bitref.get(), expected);
bitref.and(input);
assert_eq!(bitref.get(), expected & input);
bitref.set_to(expected);
}
test_and_for(bitref, expected, false);
test_and_for(bitref, expected, true);
}
test_and(&mut bitref, expected);
fn test_or(bitref: &mut BitRefMut, expected: bool) {
fn test_or_for(bitref: &mut BitRefMut, expected: bool, input: bool) {
assert_eq!(bitref.get(), expected);
bitref.or(input);
assert_eq!(bitref.get(), expected | input);
bitref.set_to(expected);
}
test_or_for(bitref, expected, false);
test_or_for(bitref, expected, true);
}
test_or(&mut bitref, expected);
}
}
}