#![allow(unused)]
use std::array::from_fn;
use crate::quad::count4::{MASKS_SCATTER, MID_MASKS_SCATTER};
#[inline(always)]
pub fn count_u8x8(word: &[u8; 8], c: u8) -> u32 {
count_u64(u64::from_le_bytes(*word), c)
}
#[inline(always)]
pub fn count_u8x16(word: &[u8; 16], c: u8) -> u32 {
count_u128(u128::from_le_bytes(*word), c)
}
#[inline(always)]
pub const fn count_u8(word: u8, c: u8) -> u32 {
let scatter = 0x55u8;
let mask = c as u8 * scatter;
let tmp = word ^ mask;
let union = (tmp | (tmp >> 1)) & scatter;
4 - union.count_ones()
}
#[inline(always)]
pub fn count_u64(word: u64, c: u8) -> u32 {
let scatter = 0x5555555555555555u64;
let mask = c as u64 * scatter;
let tmp = word ^ mask;
let union = (tmp | (tmp >> 1)) & scatter;
32 - union.count_ones()
}
#[inline(always)]
pub fn count_u64_2(word: u64, c: u8) -> u32 {
let scatter = 0x5555555555555555u64;
let masks: [u64; 4] = from_fn(|c| (c ^ 3) as u64 * scatter);
let tmp = word ^ unsafe { *masks.get_unchecked(c as usize) };
let union = (tmp & (tmp >> 1)) & scatter;
union.count_ones()
}
#[inline(always)]
pub fn count_u64_mask(word: u64, c: u8, pos: usize) -> u32 {
let scatter = 0x5555555555555555u64;
let masks: [u64; 4] = from_fn(|c| (c ^ 3) as u64 * scatter);
let tmp = word ^ unsafe { *masks.get_unchecked(c as usize) };
let union = (tmp & (tmp >> 1)) & MASKS_SCATTER[pos];
union.count_ones()
}
#[inline(always)]
pub fn count_u64_mid_mask(word: u64, c: u8, pos: usize) -> u32 {
let scatter = 0x5555555555555555u64;
let masks: [u64; 4] = from_fn(|c| (c ^ 3) as u64 * scatter);
let tmp = word ^ unsafe { *masks.get_unchecked(c as usize) };
let union = (tmp & (tmp >> 1)) & MID_MASKS_SCATTER[pos];
union.count_ones()
}
#[inline(always)]
pub fn count_u128(word: u128, c: u8) -> u32 {
let scatter = 0x55555555555555555555555555555555u128;
let mask = c as u128 * scatter;
let tmp = word ^ mask;
let union = (tmp | (tmp >> 1)) & scatter;
64 - union.count_ones()
}