Created
April 23, 2021 08:45
-
-
Save ikskuh/bb6e2e69a45ddee1a0a44ff01acdf8bb to your computer and use it in GitHub Desktop.
std::any implementation in zig
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const std = @import("std"); | |
pub fn main() !void { | |
var allocator = std.heap.page_allocator; | |
var a = try Any.init(allocator, @as(u32, 10)); | |
defer a.deinit(); | |
var b = try Any.init(allocator, @as([]const u8, "Hello, World!")); | |
defer b.deinit(); | |
std.debug.print("{s} => {d}\n", .{ | |
b.get([]const u8), | |
a.get(u32), | |
}); | |
std.debug.print("a: u32={}\t[]const u8={}\tf32={}\n", .{ | |
a.is(u32), a.is([]const u8), a.is(f32), | |
}); | |
std.debug.print("b: u32={}\t[]const u8={}\tf32={}\n", .{ | |
b.is(u32), b.is([]const u8), b.is(f32), | |
}); | |
} | |
const Any = struct { | |
allocator: *std.mem.Allocator, | |
type_key: TypeKey, | |
buffer: []u8, | |
fn init(allocator: *std.mem.Allocator, value: anytype) !Any { | |
const T = @TypeOf(value); | |
const ptr = try allocator.create(T); | |
ptr.* = value; | |
var any = Any { | |
.allocator = allocator, | |
.type_key = TypeKeyGenerator().get(@TypeOf(value)), | |
.buffer = std.mem.asBytes(ptr), | |
}; | |
std.debug.assert(any.buffer.len == @sizeOf(T)); | |
return any; | |
} | |
fn deinit(self: *Any) void { | |
self.* = undefined; | |
} | |
fn is(self: Any, comptime T: type) bool { | |
return self.type_key == TypeKeyGenerator().get(T); | |
} | |
fn get(self: *Any, comptime T: type) T { | |
std.debug.assert(self.is(T)); | |
return @ptrCast(*T, @alignCast(@alignOf(T), self.buffer.ptr)).*; | |
} | |
}; | |
const TypeKey = enum(u32) { _ }; | |
fn TypeKeyGenerator() type { | |
comptime var counter: u32 = 0; // this gets comptime closed | |
return struct { | |
pub fn get(comptime T: type) TypeKey { | |
defer counter += 1; | |
return @intToEnum(TypeKey, counter); | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment