Skip to content

Instantly share code, notes, and snippets.

@DutchGhost
Last active October 29, 2022 15:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DutchGhost/5118ebcfff05c654512f1a2f367b9157 to your computer and use it in GitHub Desktop.
Save DutchGhost/5118ebcfff05c654512f1a2f367b9157 to your computer and use it in GitHub Desktop.
//=============BUILD.ZIG===============
const std = @import("std");
pub fn build(b: *std.build.Builder) void {
// Standard release options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
const mode = b.standardReleaseOptions();
const lib = b.addStaticLibrary("SelectList", "src/main.zig");
lib.setBuildMode(mode);
lib.install();
var main_tests = b.addTest("src/main.zig");
main_tests.setBuildMode(mode);
const test_step = b.step("test", "Run library tests");
test_step.dependOn(&main_tests.step);
}
//===========================================================
//==========MAIN.ZIG=========================================
const std = @import("std");
const builtin = std.builtin;
const Type = builtin.Type;
const ArrayList = std.ArrayList;
const mem = std.mem;
const Allocator = mem.Allocator;
fn SelectList(comptime ActiveType: type, comptime types: []const type, comptime Ts: ?type) type {
comptime var fields: [types.len]Type.UnionField = undefined;
for (types) |ty, idx| {
fields[idx] = Type.UnionField{
.name = "V" ++ @typeName(ty),
.field_type = ty,
.alignment = @alignOf(ty),
};
}
const union_type: Type = .{
.Union = .{
.layout = .Auto,
.tag_type = null,
.fields = &fields,
.decls = &[_]std.builtin.Type.Declaration{},
}
};
const T: type = if(Ts) |ts| ts else @Type(union_type);
return struct {
const Self = @This();
list: ArrayList(T),
fn init(allocator: Allocator) Self {
return .{ .list = ArrayList(T).init(allocator) };
}
fn deinit(self: *Self) void {
self.list.deinit();
self.* = undefined;
}
fn append(self: *Self, value: ActiveType) !void {
try self.list.append(@unionInit(T, "V" ++ @typeName(ActiveType), value));
}
fn switchType(self: *Self, comptime NewType: type, convert: fn(ActiveType) NewType) SelectList(NewType, types, T) {
for(self.list.items) |*elem| {
var elem_ = @field(elem, "V" ++ @typeName(ActiveType));
var new = convert(elem_);
elem.* = @unionInit(T, "V" ++ @typeName(NewType), new);
}
return SelectList(NewType, types, T) { .list = self.list };
}
};
}
const testing = std.testing;
fn convertt(s: []const u8) i32 {
const fmt = std.fmt;
return fmt.parseInt(i32, s, 10) catch unreachable;
}
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{ .safety = true, .enable_memory_limit = true }){};
const alloc = gpa.allocator();
var l = SelectList([]const u8, &.{ i32, []const u8 }, null).init(alloc);
defer l.deinit();
try l.append("10");
try l.append("20");
var ll = l.switchType(i32, convertt);
//try ll.append(30);
//try ll.append(40);
for(ll.list.items) |elem| {
std.log.warn("{}", .{@field(elem, "Vi32")});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment