vsimd/
ascii.rs

1use crate::pod::POD;
2use crate::Scalable;
3
4/// An enum type which represents the case of ascii letters.
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum AsciiCase {
7    /// a-z are lower case letters.
8    Lower,
9    /// A-Z are upper case letters.
10    Upper,
11}
12
13#[inline(always)]
14fn convert_ascii_case<S: Scalable<V>, V: POD, const C: u8>(s: S, x: V) -> V {
15    assert!(matches!(C, b'A' | b'a'));
16    let x1 = s.u8xn_sub(x, s.u8xn_splat(C + 0x80));
17    let x2 = s.i8xn_lt(x1, s.i8xn_splat(-0x80 + 26));
18    let x3 = s.and(x2, s.u8xn_splat(0x20));
19    s.xor(x, x3)
20}
21
22#[inline(always)]
23pub fn to_ascii_lowercase<S: Scalable<V>, V: POD>(s: S, x: V) -> V {
24    convert_ascii_case::<S, V, b'A'>(s, x)
25}
26
27#[inline(always)]
28pub fn to_ascii_uppercase<S: Scalable<V>, V: POD>(s: S, x: V) -> V {
29    convert_ascii_case::<S, V, b'a'>(s, x)
30}
31
32#[cfg(test)]
33mod algorithm {
34    use crate::algorithm::*;
35
36    #[test]
37    #[ignore]
38    fn convert_case() {
39        let convert = |c: u8, shift: u8| {
40            let x1 = c.wrapping_sub(shift + 0x80);
41            let x2 = i8_lt(x1 as i8, -0x80 + 26);
42            let x3 = x2 & 0x20;
43            c ^ x3
44        };
45        let to_upper = |c: u8| convert(c, b'a');
46        let to_lower = |c: u8| convert(c, b'A');
47
48        print_fn_table(|c| c.is_ascii_lowercase(), to_upper);
49        print_fn_table(|c| c.is_ascii_uppercase(), to_lower);
50
51        for c in 0..=255u8 {
52            assert_eq!(to_upper(c), c.to_ascii_uppercase());
53            assert_eq!(to_lower(c), c.to_ascii_lowercase());
54        }
55    }
56}