Private helper for sliceTo(). If you want the length, use sliceTo(foo, x).len
fn lenSliceTo(ptr: anytype, comptime end: std.meta.Elem(@TypeOf(ptr))) usize
fn lenSliceTo(ptr: anytype, comptime end: std.meta.Elem(@TypeOf(ptr))) usize {
switch (@typeInfo(@TypeOf(ptr))) {
.pointer => |ptr_info| switch (ptr_info.size) {
.one => switch (@typeInfo(ptr_info.child)) {
.array => |array_info| {
if (array_info.sentinel()) |s| {
if (s == end) {
return findSentinel(array_info.child, end, ptr);
}
}
return findScalar(array_info.child, ptr, end) orelse array_info.len;
},
else => {},
},
.many => if (ptr_info.sentinel()) |s| {
if (s == end) {
return findSentinel(ptr_info.child, end, ptr);
}
// We're looking for something other than the sentinel,
// but iterating past the sentinel would be a bug so we need
// to check for both.
var i: usize = 0;
while (ptr[i] != end and ptr[i] != s) i += 1;
return i;
} else {
return findSentinel(ptr_info.child, end, @ptrCast(ptr));
},
.c => {
assert(ptr != null);
return findSentinel(ptr_info.child, end, ptr);
},
.slice => {
if (ptr_info.sentinel()) |s| {
if (s == end) {
return findSentinel(ptr_info.child, s, ptr);
}
}
return findScalar(ptr_info.child, ptr, end) orelse ptr.len;
},
},
else => {},
}
@compileError("invalid type given to std.mem.sliceTo: " ++ @typeName(@TypeOf(ptr)));
}