Skip to content

Instantly share code, notes, and snippets.

@Gonzih
Last active January 13, 2023 00:26
Show Gist options
  • Select an option

  • Save Gonzih/2b0d6e1a33f61fcc78f25c22630a5bd9 to your computer and use it in GitHub Desktop.

Select an option

Save Gonzih/2b0d6e1a33f61fcc78f25c22630a5bd9 to your computer and use it in GitHub Desktop.

Revisions

  1. Gonzih revised this gist Jan 13, 2023. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions main.zig
    Original file line number Diff line number Diff line change
    @@ -60,3 +60,6 @@ test "basic add functionality" {
    r1.add(&acc);
    try testing.expect(acc == 20);
    }


    // https://zig.news/kilianvounckx/zig-interfaces-for-the-uninitiated-an-update-4gf1
  2. Gonzih revised this gist Jan 13, 2023. 1 changed file with 19 additions and 13 deletions.
    32 changes: 19 additions & 13 deletions main.zig
    Original file line number Diff line number Diff line change
    @@ -4,27 +4,28 @@ const assert = std.debug.assert;

    pub const Runner = struct {
    const Self = @This();
    const VTable = struct { draw: *const fn (*anyopaque, *usize) void };
    const VTable = struct { add: *const fn (*anyopaque, *usize) void };

    vtable: *const VTable,
    ptr: *anyopaque,

    fn make(pointer: anytype) Self {
    const Ptr = @TypeOf(pointer);
    const ptr_info = @typeInfo(Ptr);
    const alignment = ptr_info.Pointer.alignment;

    assert(ptr_info == .Pointer);
    assert(ptr_info.Pointer.size == .One);
    assert(@typeInfo(ptr_info.Pointer.child) == .Struct);

    const gen = struct {
    fn drawImpl(ptr: *anyopaque, ctx: *usize) void {
    const self = @ptrCast(Ptr, ptr);
    try @call(.{ .modifier = .always_inline }, std.meta.Child(Ptr).draw, .{ self, ctx });
    fn addImpl(ptr: *anyopaque, ctx: *usize) void {
    const self = @ptrCast(Ptr, @alignCast(alignment, ptr));
    try @call(.{ .modifier = .always_inline }, std.meta.Child(Ptr).add, .{ self, ctx });
    }

    const vtable = VTable{
    .draw = drawImpl,
    .add = addImpl,
    };
    };

    @@ -34,23 +35,28 @@ pub const Runner = struct {
    };
    }

    fn draw(self: *@This(), ctx: *usize) void {
    self.vtable.draw(self.ptr, ctx);
    fn add(self: *@This(), ctx: *usize) void {
    self.vtable.add(self.ptr, ctx);
    }
    };

    test "basic add functionality" {
    const Runner1 = struct {
    pub fn draw(_: *@This(), acc: *usize) !void {
    acc.* += 1;
    const Self = @This();

    c: usize = 10,

    pub fn add(self: *Self, acc: *usize) !void {
    acc.* += self.c;
    }
    };

    var acc: usize = 0;
    var r = Runner1{};
    var r1 = Runner.make(&r);
    r1.draw(&acc);
    try testing.expect(acc == 1);
    r1.draw(&acc);
    try testing.expect(acc == 2);

    r1.add(&acc);
    try testing.expect(acc == 10);
    r1.add(&acc);
    try testing.expect(acc == 20);
    }
  3. Gonzih created this gist Jan 13, 2023.
    56 changes: 56 additions & 0 deletions main.zig
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,56 @@
    const std = @import("std");
    const testing = std.testing;
    const assert = std.debug.assert;

    pub const Runner = struct {
    const Self = @This();
    const VTable = struct { draw: *const fn (*anyopaque, *usize) void };

    vtable: *const VTable,
    ptr: *anyopaque,

    fn make(pointer: anytype) Self {
    const Ptr = @TypeOf(pointer);
    const ptr_info = @typeInfo(Ptr);

    assert(ptr_info == .Pointer);
    assert(ptr_info.Pointer.size == .One);
    assert(@typeInfo(ptr_info.Pointer.child) == .Struct);

    const gen = struct {
    fn drawImpl(ptr: *anyopaque, ctx: *usize) void {
    const self = @ptrCast(Ptr, ptr);
    try @call(.{ .modifier = .always_inline }, std.meta.Child(Ptr).draw, .{ self, ctx });
    }

    const vtable = VTable{
    .draw = drawImpl,
    };
    };

    return .{
    .ptr = pointer,
    .vtable = &gen.vtable,
    };
    }

    fn draw(self: *@This(), ctx: *usize) void {
    self.vtable.draw(self.ptr, ctx);
    }
    };

    test "basic add functionality" {
    const Runner1 = struct {
    pub fn draw(_: *@This(), acc: *usize) !void {
    acc.* += 1;
    }
    };

    var acc: usize = 0;
    var r = Runner1{};
    var r1 = Runner.make(&r);
    r1.draw(&acc);
    try testing.expect(acc == 1);
    r1.draw(&acc);
    try testing.expect(acc == 2);
    }