Skip to content

Instantly share code, notes, and snippets.

@alexnask
Created April 16, 2018 18:24
Show Gist options
  • Select an option

  • Save alexnask/6f8b0161b009fcb53d6afd563aa9880a to your computer and use it in GitHub Desktop.

Select an option

Save alexnask/6f8b0161b009fcb53d6afd563aa9880a to your computer and use it in GitHub Desktop.
const std = @import("std");
const warn = std.debug.warn;
const TypeId = @import("builtin").TypeId;
const VTable = struct {
accelerate_fn: fn(self: usize) void,
};
fn Unwraped(comptime T: type) type {
if (@typeId(T) == TypeId.Pointer) {
return T.Child;
}
return T;
}
fn vtable_for(comptime TWrapped: type) VTable {
const T = Unwraped(TWrapped);
return VTable {
.accelerate_fn = struct {
fn accelerate(self: usize) void {
return @intToPtr(&T, self).accelerate();
}
}.accelerate,
};
}
const Car = struct {
data: usize,
fn accelerate(self: &Car) void {
warn("VROOM VROOM\n");
}
};
const Acceleratable = struct {
vtable: &const VTable,
obj: usize,
fn init(obj: var) Acceleratable {
return Acceleratable {
.vtable = comptime &vtable_for(@typeOf(obj)),
.obj = @ptrToInt(obj),
};
}
fn accelerate(self: &Acceleratable) void {
return self.vtable.accelerate_fn(self.obj);
}
};
pub fn main() void {
var car = Car { .data = 0 };
accelerate(&Acceleratable.init(car));
}
fn accelerate(acc: &Acceleratable) void {
acc.accelerate();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment