const std = @import("std"); pub fn Vec(comptime T : type, comptime N : comptime_int) type { return packed struct { const Self = @This(); const Vals = [N]T; usingnamespace VecTypeSpecific(Self, T, N); v : Vals = [_].{0} ** N, pub fn init(v : Vals) Self { return .{.v = v}; } pub const zero: Self = comptime blk: { var v : Vals = undefined; var i = 0; inline while (i < N) : (i += 1) { v[i] = 0; } break :blk .{.v = v}; }; pub const one: Self = comptime blk: { var v : Vals = undefined; var i = 0; inline while (i < N) : (i += 1) { v[i] = 1; } break :blk .{.v = v}; }; pub const unit : [N]Self = comptime blk: { var u : [N]Self = undefined; var i = 0; inline while (i < N) : (i += 1) { u[i] = zero; u[i].v[i] = 1; } break :blk u; }; pub fn add(self : * const Self, other : Self) Self { var res : Self = undefined; comptime var i = 0; inline while(i < N) : (i += 1) { res.v[i] = self.*.v[i] + other.v[i]; } return res; } pub fn sub(self : * const Self, other : Self) Self { var res : Self = undefined; comptime var i = 0; inline while(i < N) : (i += 1) { res.v[i] = self.*.v[i] - other.v[i]; } return res; } pub fn neg(self : * const Self) Self { var res : Self = undefined; comptime var i = 0; inline while(i < N) : (i += 1) { res.v[i] = - self.*.v[i]; } return res; } pub fn len2(self : * const Self) T { var sum : T = 0; comptime var i = 0; inline while (i < N) : (i += 1) { const v = self.*.v[i]; sum += v * v; } return sum; } pub fn dot(self : * const Self, other : Self) T { var sum : T = 0; comptime var i = 0; inline while(i < N) : (i += 1) { sum += self.*.v[i] * other.v[i]; } return sum; } }; } fn VecTypeSpecific(comptime Self : type, comptime T : type, comptime N : comptime_int) type { return switch (@typeInfo(T)) { .Float => struct { pub fn len(self : * const Self) T { return @sqrt(self.len2()); } }, .Int => struct { }, else => struct { }, }; } // const _v2f : Vec(f32, 2) align(4) = undefined; // pub const v2f = @TypeOf(_v2f); pub const v2f = Vec(f32, 2); pub const v3f = Vec(f32, 3); pub const v2i = Vec(i32, 2); pub const v3i = Vec(i32, 3); const expect = std.testing.expect; test "vector tests" { const unit = v3f.unit; expect(unit[2].v[0] == 0); expect(unit[2].v[1] == 0); expect(unit[2].v[2] == 1); var v = unit[0].add(unit[1]); expect(v.v[0] == 1); expect(v.v[1] == 1); expect(v.v[2] == 0); expect(v.len2() == 2); expect(v.len() == @sqrt(2.0)); expect(v3i.one.len2() == 3); }