Skip to content

Instantly share code, notes, and snippets.

@phase
Last active May 10, 2024 05:19
Show Gist options
  • Save phase/d730a1efb34f7debc5c63f9120617745 to your computer and use it in GitHub Desktop.
Save phase/d730a1efb34f7debc5c63f9120617745 to your computer and use it in GitHub Desktop.
denyCapabilities.zig - almost Pony's reference capabilities in Zig
// Tested with Zig 0.12.0
const std = @import("std");
const assert = std.debug.assert;
const Cap = enum { iso, trn, val, ref, box, tag };
fn aliasCap(cap: Cap) Cap {
return switch (cap) {
.iso => .tag,
.trn => .box,
else => cap,
};
}
fn canSend(cap: Cap) bool {
return switch (cap) {
.iso, .trn, .val => true,
else => false,
};
}
fn Ref(comptime cap: Cap, comptime T: type) type {
return struct {
const Self = @This();
raw_ptr: *T,
comptime cap: Cap = cap,
fn new(raw_ptr: *T) Self {
return Self{ .raw_ptr = raw_ptr };
}
fn raw(self: Self) *T {
comptime if (cap == .tag) {
@compileError("Can't dereference .tag");
};
return self.raw_ptr;
}
fn alias(self: Self) Ref(aliasCap(cap), T) {
return Ref(aliasCap(cap), T).new(self.raw_ptr);
}
};
}
test {
var value: i32 = 5;
var x: Ref(.iso, i32) = Ref(.iso, i32).new(&value);
const y = x.alias();
assert(y.cap == Cap.tag);
// assert(y.raw().* == x.raw().*); -- y.raw() errors because y is .tag
assert(@sizeOf(@TypeOf(x)) == @sizeOf(*i32));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment