Skip to content

Instantly share code, notes, and snippets.

@travisstaloch
Last active December 10, 2023 09:16
Show Gist options
  • Save travisstaloch/6ffee43044678d898b9c5bfa79c98e61 to your computer and use it in GitHub Desktop.
Save travisstaloch/6ffee43044678d898b9c5bfa79c98e61 to your computer and use it in GitHub Desktop.
A nice way to represent vectors in zig. Mixin methods + usingnamespace allow all types to share code. extern structs mean they can bitcast to/from arrays and simd vectors.
pub fn VecMethods(comptime Self: type) type {
return struct {
const info = @typeInfo(Self);
pub const len = info.Struct.fields.len;
pub const Arr = [len]info.Struct.fields[0].type;
pub const Simd = @Vector(len, info.Struct.fields[0].type);
pub fn arr(self: Self) Arr {
return @bitCast(self);
}
pub fn initArr(a: Arr) Self {
return @bitCast(a);
}
pub fn simd(self: Self) Simd {
return @bitCast(self);
}
pub fn initSimd(v: Simd) Self {
return @bitCast(v);
}
pub fn add(a: Self, b: Self) Self {
return initSimd(a.simd() + b.simd());
}
// TODO add more useful shared methods
};
}
pub fn Vec2(comptime T: type) type {
return extern struct {
x: T,
y: T,
pub usingnamespace VecMethods(@This());
};
}
pub fn Vec3(comptime T: type) type {
return extern struct {
x: T,
y: T,
z: T,
pub usingnamespace VecMethods(@This());
};
}
const std = @import("std");
test {
inline for ([_]type{ u8, u32, usize, f32, f64 }) |Child| {
{
const cx2 = Vec2(Child);
const x = cx2.initArr(.{ 1, 1 });
const y = cx2.initArr(.{ 1, 2 });
try std.testing.expectEqual(cx2.initArr(.{ 2, 3 }), x.add(y));
}
{
const cx3 = Vec3(Child);
const x = cx3.initArr(.{ 1, 1, 1 });
const y = cx3.initArr(.{ 1, 2, 3 });
try std.testing.expectEqual(cx3.initArr(.{ 2, 3, 4 }), x.add(y));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment