const std = @import("std");
pub fn export_fn(comptime f: *const anyopaque, comptime name: []const u8) void {
comptime @export(f, .{
.name = name,
.linkage = .strong
});
}
pub fn ReprCSlice(comptime T: type) type {
return extern struct {
ptr: ?[*]T,
len: usize,
pub inline fn from_slice(slice: ?[]const T) @This() {
if (slice) |s| {
return .{ .ptr = @constCast(s.ptr), .len = s.len };
} else {
return .{ .ptr = null, .len = 0 };
}
}
pub inline fn from_ptr_len(ptr: ?[*]const T, len: usize) @This() {
if (ptr) |p| {
return @This().from_slice(p[0..len]);
} else {
return @This().from_slice(null);
}
}
pub inline fn to_slice(self: @This()) ?[]T {
if (self.ptr) |ptr| {
return ptr[0..self.len];
} else {
return null;
}
}
};
}
comptime {
const assert = @import("std").debug.assert;
// smoke tests
_ = ReprCSlice(u8).from_slice("awawawawawwawa").to_slice();
// size/align assertions
assert(@sizeOf(ReprCSlice(u8)) == 2 * @sizeOf(usize));
assert(@alignOf(ReprCSlice(u8)) == @alignOf(usize));
assert(@sizeOf(ReprCSlice(u128)) == 2 * @sizeOf(usize));
assert(@alignOf(ReprCSlice(u128)) == @alignOf(usize));
}