#![allow(unsafe_op_in_unsafe_fn)]
use super::generic;
use crate::{get_chars_table, Output};
use core::simd::prelude::*;
type Simd = u8x16;
pub(crate) const USE_CHECK_FN: bool = true;
pub(crate) unsafe fn encode<const UPPER: bool>(input: &[u8], output: impl Output) {
let hex_table = Simd::from_array(*get_chars_table::<UPPER>());
generic::encode_unaligned_chunks::<UPPER, _, _>(input, output, |chunk: Simd| {
let mut lo = chunk & Simd::splat(15);
let mut hi = chunk >> Simd::splat(4);
lo = hex_table.swizzle_dyn(lo);
hi = hex_table.swizzle_dyn(hi);
let (hex_lo, hex_hi) = Simd::interleave(hi, lo);
[hex_lo, hex_hi]
});
}
pub(crate) fn check(input: &[u8]) -> bool {
generic::check_unaligned_chunks(input, |chunk: Simd| {
let valid_digit = chunk.simd_ge(Simd::splat(b'0')) & chunk.simd_le(Simd::splat(b'9'));
let valid_upper = chunk.simd_ge(Simd::splat(b'A')) & chunk.simd_le(Simd::splat(b'F'));
let valid_lower = chunk.simd_ge(Simd::splat(b'a')) & chunk.simd_le(Simd::splat(b'f'));
let valid = valid_digit | valid_upper | valid_lower;
valid.all()
})
}
pub(crate) use generic::decode_checked;
pub(crate) use generic::decode_unchecked;