use core::{mem, ptr};
use super::bitmask::BitMask;
cfg_if! {
if #[cfg(any(
target_pointer_width = "64",
target_arch = "aarch64",
target_arch = "x86_64",
target_arch = "wasm32",
))] {
type GroupWord = u64;
type NonZeroGroupWord = core::num::NonZeroU64;
} else {
type GroupWord = u32;
type NonZeroGroupWord = core::num::NonZeroU32;
}
}
pub(crate) type BitMaskWord = GroupWord;
pub(crate) type NonZeroBitMaskWord = NonZeroGroupWord;
pub(crate) const BITMASK_STRIDE: usize = 8;
pub(crate) const BITMASK_ITER_MASK: BitMaskWord = !0;
#[inline]
fn repeat(byte: u8) -> GroupWord {
GroupWord::from_ne_bytes([byte; Group::WIDTH])
}
#[derive(Copy, Clone)]
#[repr(transparent)]
pub(crate) struct Group(GroupWord);
#[allow(clippy::use_self)]
impl Group {
pub(crate) const WIDTH: usize = mem::size_of::<Self>();
#[cfg(any(
target_pointer_width = "64",
target_arch = "aarch64",
target_arch = "x86_64",
target_arch = "wasm32",
))]
pub(crate) const LOWEST_MASK: [BitMaskWord; Group::WIDTH] = [
0x0000_0000_0000_0000,
0x0000_0000_0000_0080,
0x0000_0000_0000_8080,
0x0000_0000_0080_8080,
0x0000_0000_8080_8080,
0x0000_0080_8080_8080,
0x0000_8080_8080_8080,
0x0080_8080_8080_8080,
];
#[cfg(not(any(
target_pointer_width = "64",
target_arch = "aarch64",
target_arch = "x86_64",
target_arch = "wasm32",
)))]
pub(crate) const LOWEST_MASK: [BitMaskWord; Group::WIDTH] =
[0x0000_0000, 0x0000_0080, 0x0000_8080, 0x0080_8080];
#[inline]
#[allow(clippy::cast_ptr_alignment)] pub(crate) unsafe fn load(ptr: *const u8) -> Self {
Group(ptr::read_unaligned(ptr.cast()))
}
#[inline]
pub(crate) fn match_byte(self, byte: u8) -> BitMask {
let cmp = self.0 ^ repeat(byte);
BitMask((cmp.wrapping_sub(repeat(0x01)) & !cmp & repeat(0x80)).to_le())
}
}