aboutsummaryrefslogtreecommitdiff
path: root/src/global.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/global.zig')
-rw-r--r--src/global.zig61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/global.zig b/src/global.zig
index 25b908543..e90a1beec 100644
--- a/src/global.zig
+++ b/src/global.zig
@@ -95,3 +95,64 @@ pub const MAX_PATH_BYTES: usize = if (Environment.isWasm) 1024 else std.fs.MAX_P
pub inline fn cast(comptime To: type, value: anytype) To {
return @ptrCast(To, @alignCast(@alignOf(To), value));
}
+
+extern fn strlen(ptr: [*c]const u8) usize;
+pub fn indexOfSentinel(comptime Elem: type, comptime sentinel: Elem, ptr: [*:sentinel]const Elem) usize {
+ if (comptime Elem == u8 and sentinel == 0) {
+ return strlen(ptr);
+ } else {
+ var i: usize = 0;
+ while (ptr[i] != sentinel) {
+ i += 1;
+ }
+ return i;
+ }
+}
+
+pub fn len(value: anytype) usize {
+ return switch (@typeInfo(@TypeOf(value))) {
+ .Array => |info| info.len,
+ .Vector => |info| info.len,
+ .Pointer => |info| switch (info.size) {
+ .One => switch (@typeInfo(info.child)) {
+ .Array => value.len,
+ else => @compileError("invalid type given to std.mem.len"),
+ },
+ .Many => {
+ const sentinel_ptr = info.sentinel orelse
+ @compileError("length of pointer with no sentinel");
+ const sentinel = @ptrCast(*const info.child, sentinel_ptr).*;
+
+ return indexOfSentinel(info.child, sentinel, value);
+ },
+ .C => {
+ std.debug.assert(value != null);
+ return indexOfSentinel(info.child, 0, value);
+ },
+ .Slice => value.len,
+ },
+ .Struct => |info| if (info.is_tuple) {
+ return info.fields.len;
+ } else @compileError("invalid type given to std.mem.len"),
+ else => @compileError("invalid type given to std.mem.len"),
+ };
+}
+
+pub fn span(ptr: anytype) std.mem.Span(@TypeOf(ptr)) {
+ if (@typeInfo(@TypeOf(ptr)) == .Optional) {
+ if (ptr) |non_null| {
+ return span(non_null);
+ } else {
+ return null;
+ }
+ }
+ const Result = std.mem.Span(@TypeOf(ptr));
+ const l = len(ptr);
+ const ptr_info = @typeInfo(Result).Pointer;
+ if (ptr_info.sentinel) |s_ptr| {
+ const s = @ptrCast(*const ptr_info.child, s_ptr).*;
+ return ptr[0..l :s];
+ } else {
+ return ptr[0..l];
+ }
+}