use std::fmt::Debug;
use std::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
use std::hash::Hash;
use rand::Rand;
pub trait Bigwise : Rand + Debug + Eq + Copy + Hash + Default + Ord
+ BitAnd<Output = Self>
+ BitOr<Output = Self>
+ BitXor<Output = Self>
+ Not<Output = Self>
+ Shl<u32, Output = Self>
+ Shr<u32, Output = Self>
+ IntoIterator<Item=bool, IntoIter=BitsIter<Self>>
{
fn size() -> u32;
fn empty() -> Self;
fn full() -> Self;
fn from_bytes(byte: &[u8]) -> Self;
fn to_bytes(self) -> Vec<u8>;
fn get(self, i: u32) -> bool;
fn set(&mut self, i: u32, v: bool);
fn rotate_left(self, n: u32) -> Self;
fn rotate_right(self, n: u32) -> Self;
}
pub struct BitsIter<T: Bigwise> {
bw: T,
idx: u32,
}
impl<T: Bigwise> BitsIter<T> {
pub fn new(bw: T) -> BitsIter<T> {
BitsIter { bw: bw, idx: 0 }
}
}
impl<T: Bigwise> Iterator for BitsIter<T> {
type Item = bool;
fn next(&mut self) -> Option<Self::Item> {
if self.idx < T::size() {
let res = Some(self.bw.get(self.idx));
self.idx += 1;
res
} else {
None
}
}
}