use std::marker::PhantomData;
use crate::bit_block::BitBlock;
use crate::cache;
use crate::cache::ReduceCache;
use crate::primitive_array::PrimitiveArray;
type DefaultCache = cache::FixedCache<32>;
pub trait Config: 'static {
type Level0BitBlock: BitBlock;
type Level0BlockIndices: PrimitiveArray;
type Level1BitBlock: BitBlock;
type Level1BlockIndices: PrimitiveArray;
type DataBitBlock: BitBlock;
const MAX_CAPACITY: usize;
const MAX_MASK_ALIGN: usize;
type DefaultCache: ReduceCache;
}
pub(crate) type Lvl0Mask<Conf> = <Conf as Config>::Level0BitBlock;
pub(crate) type Lvl1Mask<Conf> = <Conf as Config>::Level1BitBlock;
pub(crate) type DataMask<Conf> = <Conf as Config>::DataBitBlock;
pub(crate) type Lvl0Index<Conf> = <<Conf as Config>::Level0BlockIndices as PrimitiveArray>::Item;
pub(crate) type Lvl1Index<Conf> = <<Conf as Config>::Level1BlockIndices as PrimitiveArray>::Item;
const fn usize_max(left: usize, right: usize) -> usize {
if left < right{
right
} else {
left
}
}
const fn max_mask_align<Conf: Config>() -> usize {
usize_max(align_of::<Conf::Level0BitBlock>(),
usize_max(
align_of::<Conf::Level1BitBlock>(),
align_of::<Conf::DataBitBlock>()
)
)
}
const fn max_capacity<Conf: Config>() -> usize {
(1 << Conf::Level0BitBlock::SIZE_POT_EXPONENT)
* (1 << Conf::Level1BitBlock::SIZE_POT_EXPONENT)
* (1 << Conf::DataBitBlock::SIZE_POT_EXPONENT)
}
const fn block_bit_size<Block: BitBlock>() -> usize{
1 << Block::SIZE_POT_EXPONENT
}
#[derive(Default)]
pub struct _64bit<
DataBitBlock: BitBlock = u64,
DefaultCache: ReduceCache = self::DefaultCache
>(PhantomData<(DataBitBlock, DefaultCache)>);
impl<DataBitBlock: BitBlock, DefaultCache: ReduceCache> Config for
_64bit<DataBitBlock, DefaultCache>
{
type Level0BitBlock = u64;
type Level0BlockIndices = [u8; 64];
type Level1BitBlock = u64;
type Level1BlockIndices = [u16; 64];
type DataBitBlock = DataBitBlock;
const MAX_CAPACITY: usize = max_capacity::<Self>();
const MAX_MASK_ALIGN: usize = max_mask_align::<Self>();
type DefaultCache = DefaultCache;
}
#[cfg(feature = "simd")]
#[cfg_attr(docsrs, doc(cfg(feature = "simd")))]
#[derive(Default)]
pub struct _128bit<
DataBitBlock: BitBlock = wide::u64x2,
DefaultCache: ReduceCache = self::DefaultCache
>(PhantomData<(DataBitBlock, DefaultCache)>);
#[cfg(feature = "simd")]
#[cfg_attr(docsrs, doc(cfg(feature = "simd")))]
impl<DataBitBlock: BitBlock, DefaultCache: ReduceCache> Config for
_128bit<DataBitBlock, DefaultCache>
{
type Level0BitBlock = wide::u64x2;
type Level0BlockIndices = [u8; 128];
type Level1BitBlock = wide::u64x2;
type Level1BlockIndices = [u16; 128];
type DataBitBlock = wide::u64x2;
const MAX_CAPACITY: usize = max_capacity::<Self>();
const MAX_MASK_ALIGN: usize = max_mask_align::<Self>();
type DefaultCache = DefaultCache;
}
#[cfg(feature = "simd")]
#[cfg_attr(docsrs, doc(cfg(feature = "simd")))]
#[derive(Default)]
pub struct _256bit<
DataBitBlock: BitBlock = wide::u64x4,
DefaultCache: ReduceCache = self::DefaultCache
>(PhantomData<(DataBitBlock, DefaultCache)>);
#[cfg(feature = "simd")]
#[cfg_attr(docsrs, doc(cfg(feature = "simd")))]
impl<DataBitBlock: BitBlock, DefaultCache: ReduceCache> Config for
_256bit<DataBitBlock, DefaultCache>
{
type Level0BitBlock = wide::u64x4;
type Level0BlockIndices = [u8; 256];
type Level1BitBlock = wide::u64x4;
type Level1BlockIndices = [u16; 256];
type DataBitBlock = DataBitBlock;
const MAX_CAPACITY: usize = max_capacity::<Self>()
- (1 * 256 * block_bit_size::<DataBitBlock>());
const MAX_MASK_ALIGN: usize = max_mask_align::<Self>();
type DefaultCache = DefaultCache;
}