authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-01-20 23:19:12 -08:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-01-20 23:19:12 -08:00
log338a9cb2ecb894ee599e422d454fad96e5cb8c96
tree2d8d06629f10bfa3273576f0c27fa92c202c5439
parent1a28511f024ee69b3b35f125a6d72ac6fa3cc7c8

add a helper find() method to UnicodeData


2 files changed, 52 insertions(+), 0 deletions(-)

scripts/UnicodeData.zig+26
......@@ -8,6 +8,7 @@ pub usingnamespace common.Main(struct {
88
99 pub const dest_header =
1010 \\const ucd = @import("./lib.zig");
11 \\const std = @import("std");
1112 \\
1213 \\pub const Codepoint = struct {
1314 \\ u21, // U+ code
......@@ -47,6 +48,31 @@ pub usingnamespace common.Main(struct {
4748 \\ narrow,
4849 \\};
4950 \\
51 \\pub fn find(cp: u21) Codepoint {
52 \\ return data[binarySearchClosest(Codepoint, &data, cp, compare)];
53 \\}
54 \\
55 \\fn binarySearchClosest(comptime T: type, items: []const T, context: anytype, comptime compareFn: fn (@TypeOf(context), T) std.math.Order) usize {
56 \\ var low: usize = 0;
57 \\ var high: usize = items.len;
58 \\ while (low < high) {
59 \\ const mid = low + (high - low) / 2;
60 \\ switch (compareFn(context, items[mid])) {
61 \\ .eq => return mid,
62 \\ .gt => low = mid + 1,
63 \\ .lt => high = mid,
64 \\ }
65 \\ }
66 \\ std.debug.assert(low == high);
67 \\ return high;
68 \\}
69 \\
70 \\pub fn compare(needle: u21, row: Codepoint) std.math.Order {
71 \\ if (needle < row[0]) return .lt;
72 \\ if (needle > row[0]) return .gt;
73 \\ return .eq;
74 \\}
75 \\
5076 \\pub const data = [_]Codepoint{
5177 \\
5278 ;
src/unicode_data.zig+26
......@@ -6,6 +6,7 @@
66// zig fmt: off
77
88const ucd = @import("./lib.zig");
9const std = @import("std");
910
1011pub const Codepoint = struct {
1112 u21, // U+ code
......@@ -45,6 +46,31 @@ pub const Decomposition = enum {
4546 narrow,
4647};
4748
49pub fn find(cp: u21) Codepoint {
50 return data[binarySearchClosest(Codepoint, &data, cp, compare)];
51}
52
53fn binarySearchClosest(comptime T: type, items: []const T, context: anytype, comptime compareFn: fn (@TypeOf(context), T) std.math.Order) usize {
54 var low: usize = 0;
55 var high: usize = items.len;
56 while (low < high) {
57 const mid = low + (high - low) / 2;
58 switch (compareFn(context, items[mid])) {
59 .eq => return mid,
60 .gt => low = mid + 1,
61 .lt => high = mid,
62 }
63 }
64 std.debug.assert(low == high);
65 return high;
66}
67
68pub fn compare(needle: u21, row: Codepoint) std.math.Order {
69 if (needle < row[0]) return .lt;
70 if (needle > row[0]) return .gt;
71 return .eq;
72}
73
4874pub const data = [_]Codepoint{
4975 .{ 0x0000, "<control>", .Cc, 0, .BN, .__none, &.{}, "", "", "", false, null, null, null, },
5076 .{ 0x0001, "<control>", .Cc, 0, .BN, .__none, &.{}, "", "", "", false, null, null, null, },