use std::simd::{
Simd,
cmp::{SimdPartialEq, SimdPartialOrd},
};
#[inline(always)]
pub fn skip_ascii_simd(bytes: &[u8], offset: usize) -> usize {
if offset >= bytes.len() || bytes[offset] >= 0x80 {
return offset;
}
let mut offset = offset;
const LANES: usize = 16;
let threshold = Simd::<u8, LANES>::splat(0x80u8);
while offset + LANES <= bytes.len() {
let chunk = Simd::<u8, LANES>::from_slice(&bytes[offset..]);
let mask = chunk.simd_ge(threshold).to_bitmask();
if mask != 0 {
offset += mask.trailing_zeros() as usize;
return offset;
}
offset += LANES;
}
while offset < bytes.len() && bytes[offset] < 0x80 {
offset += 1;
}
offset
}
#[inline(always)]
pub fn simd_ascii_delete_mask(chunk: Simd<u8, 16>, ascii_lut: Simd<u8, 16>) -> u64 {
let byte_idx = chunk >> Simd::<u8, 16>::splat(3);
let lut_byte = ascii_lut.swizzle_dyn(byte_idx);
const SHIFT_TABLE: [u8; 16] = [1, 2, 4, 8, 16, 32, 64, 128, 1, 2, 4, 8, 16, 32, 64, 128];
let shift_table = Simd::<u8, 16>::from_array(SHIFT_TABLE);
let bit_pos = chunk & Simd::<u8, 16>::splat(7);
let bit_mask = shift_table.swizzle_dyn(bit_pos);
(lut_byte & bit_mask)
.simd_ne(Simd::<u8, 16>::splat(0))
.to_bitmask()
}
#[inline(always)]
pub fn skip_non_digit_ascii_simd(bytes: &[u8], offset: usize) -> usize {
if offset >= bytes.len() {
return offset;
}
let b0 = bytes[offset];
if b0 >= 0x80 || (0x30..=0x39).contains(&b0) {
return offset;
}
let mut offset = offset;
const LANES: usize = 16;
let non_ascii = Simd::<u8, LANES>::splat(0x80u8);
let digit_lo = Simd::<u8, LANES>::splat(0x30u8);
let digit_hi = Simd::<u8, LANES>::splat(0x3Au8);
while offset + LANES <= bytes.len() {
let chunk = Simd::<u8, LANES>::from_slice(&bytes[offset..]);
let is_non_ascii = chunk.simd_ge(non_ascii);
let is_digit = chunk.simd_ge(digit_lo) & chunk.simd_lt(digit_hi);
let stop_mask = (is_non_ascii | is_digit).to_bitmask();
if stop_mask != 0 {
offset += stop_mask.trailing_zeros() as usize;
return offset;
}
offset += LANES;
}
while offset < bytes.len() {
let b = bytes[offset];
if b >= 0x80 || (0x30..=0x39).contains(&b) {
break;
}
offset += 1;
}
offset
}