Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- fn AsRef(comptime SELF: type, comptime Target: type) type {
- return struct {
- pub fn REQUIRE_as_ref(self: *const SELF) *const Target {
- return undefined;
- }
- };
- }
- fn AsMut(comptime SELF: type, comptime Target: type) type {
- comptime {
- require(AsRef(SELF, Target), SELF, "AsRef is a superset of AsMut, and should therefore be implemented.");
- }
- return struct {
- pub fn REQUIRE_as_mut(self: *SELF) *Target {
- return undefined;
- }
- pub fn update(item: *SELF, new: Target) void {
- item.as_mut().* = new;
- }
- };
- }
- fn require(comptime TRAIT: var, comptime CHECK: var, comptime msg: []const u8) void {
- const fn_names_to_check = @typeInfo(TRAIT).Struct;
- const to_check_type_info = @typeInfo(CHECK).Struct;
- inline for(fn_names_to_check.defs) |name| {
- inline for (to_check_type_info.defs) |def| {
- if (mem.eql(u8, name.name[0..7], "REQUIRE")) {
- if(mem.eql(u8, name.name[8..], def.name)) {
- if (mem.eql(u8, @typeName(name.data.Fn.fn_type), @typeName(def.data.Fn.fn_type))) {
- return;
- }
- }
- }
- }
- }
- @compileError(msg);
- }
- const thingy = struct {
- data: usize,
- pub fn next(self: *this) ?u32 {
- return 10;
- }
- pub fn as_ref(self: *const this) *const usize {
- return &(self.data);
- }
- pub fn as_mut(self: *this) *usize {
- return &(self.data);
- }
- };
- pub fn test_asref(comptime T: type, item: T) void {
- comptime {
- require(AsRef(T, usize), T, "T needs to implement AsRef");
- }
- std.debug.warn("data: {}\n", item.as_ref().* );
- }
- pub fn test_asmut(comptime T: type, item: *T) void {
- comptime {
- require(AsMut(T, usize), T, "T needs to implement AsMut");
- }
- AsMut(T, usize).update(item, 100);
- std.debug.warn("data: {}\n", item.as_ref().* );
- }
- pub fn repro(comptime T: type, item: T) void {
- comptime {
- require(AsMut(T, usize), T, "T needs to implement AsMut");
- }
- var ptr = item.as_mut();
- std.debug.warn("data: {}\n", item.as_ref().* );
- }
- pub fn main() void {
- var thing = thingy { .data = 10 };
- test_asmut(thingy, &thing);
- std.debug.warn("after test_asmut: {}\n", thing.data);
- repro(thingy, thing);
- }
Advertisement
Add Comment
Please, Sign In to add comment