summaryrefslogtreecommitdiff
path: root/src/ascii.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/ascii.zig')
-rw-r--r--src/ascii.zig33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/ascii.zig b/src/ascii.zig
new file mode 100644
index 0000000..6c28f25
--- /dev/null
+++ b/src/ascii.zig
@@ -0,0 +1,33 @@
1const std = @import("std");
2const simd = std.simd;
3const testing = std.testing;
4
5/// Returns true if `str` only contains ASCII bytes. Uses SIMD if possible.
6pub fn isAsciiOnly(str: []const u8) bool {
7 const vec_len = simd.suggestVectorLength(u8) orelse return for (str) |b| {
8 if (b > 127) break false;
9 } else true;
10
11 const Vec = @Vector(vec_len, u8);
12 var remaining = str;
13
14 while (true) {
15 if (remaining.len < vec_len) return for (remaining) |b| {
16 if (b > 127) break false;
17 } else true;
18
19 const v1 = remaining[0..vec_len].*;
20 const v2: Vec = @splat(127);
21 if (@reduce(.Or, v1 > v2)) return false;
22 remaining = remaining[vec_len..];
23 }
24
25 return true;
26}
27
28test "isAsciiOnly" {
29 const ascii_only = "Hello, World! 0123456789 !@#$%^&*()_-=+";
30 try testing.expect(isAsciiOnly(ascii_only));
31 const not_ascii_only = "Héllo, World! 0123456789 !@#$%^&*()_-=+";
32 try testing.expect(!isAsciiOnly(not_ascii_only));
33}