1use crate::pod::POD;
2use crate::Scalable;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum AsciiCase {
7 Lower,
9 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}