use Bigwise;
use BitsIter;
use std::fmt::{self, Debug, Formatter};
use std::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
use rand::{Rand, Rng};
#[derive(Copy, Clone, Eq, PartialEq, Hash, Default, Ord, PartialOrd)]
pub struct Bw64(u64);
impl Bigwise for Bw64 {
fn size() -> u32 {
64
}
fn empty() -> Self {
Bw64(0)
}
fn full() -> Self {
Bw64(!0)
}
fn from_bytes(bytes: &[u8]) -> Self {
let mut val = 0u64;
for (i, &b) in bytes.iter().rev().take(8).enumerate() {
val |= (b as u64) << (8*i);
}
Bw64(val)
}
fn to_bytes(self) -> Vec<u8> {
let nb_bytes = (Self::size() / 8) as usize;
let mut res = Vec::with_capacity(nb_bytes);
for i in (0..nb_bytes).rev() {
res.push(((self.0 >> (8*i)) & 0xFF) as u8);
}
res
}
fn get(self, i: u32) -> bool {
if i >= Self::size() {
false
} else {
(self.0 >> i) & 1 > 0
}
}
fn set(&mut self, i: u32, v: bool) {
if i >= Self::size() {
panic!("index overflow");
}
if v {
self.0 |= 1 << i;
} else {
self.0 &= !(1 << i);
}
}
fn rotate_left(self, n: u32) -> Self {
Bw64(self.0.rotate_left(n))
}
fn rotate_right(self, n: u32) -> Self {
Bw64(self.0.rotate_right(n))
}
}
impl Rand for Bw64 {
fn rand<R: Rng>(rng: &mut R) -> Self {
Bw64(rng.next_u64())
}
}
impl Debug for Bw64 {
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
let bytes = self.to_bytes();
for b in bytes {
try!(f.write_str(&format!("{:08b}", b)));
}
Ok(())
}
}
impl BitAnd for Bw64 {
type Output = Self;
fn bitand(self, rhs: Self) -> Self {
Bw64(self.0 & rhs.0)
}
}
impl BitOr for Bw64 {
type Output = Self;
fn bitor(self, rhs: Self) -> Self {
Bw64(self.0 | rhs.0)
}
}
impl BitXor for Bw64 {
type Output = Self;
fn bitxor(self, rhs: Self) -> Self {
Bw64(self.0 ^ rhs.0)
}
}
impl Not for Bw64 {
type Output = Self;
fn not(self) -> Self {
Bw64(!self.0)
}
}
impl Shl<u32> for Bw64 {
type Output = Self;
fn shl(self, rhs: u32) -> Self {
if rhs >= Self::size() {
Self::empty()
} else {
Bw64(self.0 << rhs)
}
}
}
impl Shr<u32> for Bw64 {
type Output = Self;
fn shr(self, rhs: u32) -> Self {
if rhs >= Self::size() {
Self::empty()
} else {
Bw64(self.0 >> rhs)
}
}
}
impl IntoIterator for Bw64 {
type Item = bool;
type IntoIter = BitsIter<Self>;
fn into_iter(self) -> Self::IntoIter {
BitsIter::new(self)
}
}