use super::*;
use std::mem;
use std::ops::Range;
use proptest::bits::{BitSetLike, BitSetStrategy};
use bit_set::BitSet;
use self::BitsParams::*;
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum BitsParams<A> {
Ranged(Range<usize>),
Masked(A),
}
pub trait AllOnes {
fn all_ones() -> Self;
}
macro_rules! allones_impls {
($($typ: ty),*) => {
$(
impl AllOnes for $typ {
fn all_ones() -> Self { !(0 as $typ) }
}
)*
};
}
allones_impls!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
impl<A: AllOnes + BitSetLike> Default for BitsParams<A> {
fn default() -> Self {
(A::all_ones(),).into()
}
}
impl Default for BitsParams<BitSet> {
fn default() -> Self {
Ranged(0..(mem::size_of::<usize>() * 8).pow(2))
}
}
impl<A: BitSetLike> From<(A,)> for BitsParams<A> {
fn from(x: (A,)) -> Self {
Masked(x.0)
}
}
impl<A> From<Range<usize>> for BitsParams<A> {
fn from(x: Range<usize>) -> Self {
Ranged(x)
}
}
impl<T: BitSetLike> Bits<T> {
pub fn new(t: T) -> Self {
t.into()
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug,
From,
Not, Neg, BitAnd, BitOr, BitXor,
Add, Sub, AddAssign, SubAssign, Mul, Div, Rem, Shr, Shl)]
#[cfg_attr(feature = "frunk", derive(Generic))]
pub struct Bits<T: BitSetLike>(T);
macro_rules! impl_bits {
($($typ: ty),*) => {
$(
impl From<Bits<Self>> for $typ {
fn from(x: Bits<Self>) -> Self { x.0 }
}
arbitrary_for!([] Bits<$typ>,
FromMapStrategy<BitSetStrategy<$typ>, Self>,
BitsParams<$typ>,
args => from_map_strategy(match args {
Ranged(r) => BitSetStrategy::new(r.start, r.end),
Masked(m) => BitSetStrategy::masked(m),
})
);
)*
};
}
impl_bits!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize, BitSet);