Virtual contiguous view over multiple slices (zero-copy)
const MultiSliceView = struct
const MultiSliceView = struct {
slices: [3][]const u8,
offsets: [4]usize,
fn init(s1: []const u8, s2: []const u8, s3: []const u8) MultiSliceView {
return .{
.slices = .{ s1, s2, s3 },
.offsets = .{
0,
s1.len,
s1.len + s2.len,
s1.len + s2.len + s3.len,
},
};
}
fn totalLen(self: *const MultiSliceView) usize {
return self.offsets[3];
}
/// Get byte at position (zero-copy)
fn getByte(self: *const MultiSliceView, pos: usize) u8 {
for (0..3) |i| {
if (pos >= self.offsets[i] and pos < self.offsets[i + 1]) {
return self.slices[i][pos - self.offsets[i]];
}
}
unreachable;
}
/// Try to get a contiguous slice [start..end) - returns null if spans boundaries
fn tryGetSlice(self: *const MultiSliceView, start: usize, end: usize) ?[]const u8 {
for (0..3) |i| {
if (start >= self.offsets[i] and end <= self.offsets[i + 1]) {
const local_start = start - self.offsets[i];
const local_end = end - self.offsets[i];
return self.slices[i][local_start..local_end];
}
}
return null;
}
/// Copy range [start..end) to buffer (used when slice spans boundaries)
fn copyRange(self: *const MultiSliceView, start: usize, end: usize, buffer: []u8) void {
var pos: usize = 0;
for (start..end) |i| {
buffer[pos] = self.getByte(i);
pos += 1;
}
}
}