diff --git a/src/Dimensions.zig b/src/Dimensions.zig index 3953fe0..58852c7 100644 --- a/src/Dimensions.zig +++ b/src/Dimensions.zig @@ -68,10 +68,17 @@ pub fn set(comptime self: *Self, comptime key: Dimension, comptime val: i8) void self.data.set(key, val); } +pub fn argsOpt(self: Self) ArgOpts { + var args: ArgOpts = undefined; + inline for (std.enums.values(Dimension)) |d| + @field(args, @tagName(d)) = self.get(d); + return args; +} + /// Add exponents component-wise. Used internally by `mulBy`. pub fn add(comptime a: Self, comptime b: Self) Self { var result = Self.initFill(0); - for (std.enums.values(Dimension)) |d| + inline for (std.enums.values(Dimension)) |d| result.set(d, a.get(d) + b.get(d)); return result; } diff --git a/src/Scalar.zig b/src/Scalar.zig index d0a5d87..a93509c 100644 --- a/src/Scalar.zig +++ b/src/Scalar.zig @@ -30,7 +30,7 @@ pub fn isScalarType(comptime T: type) bool { pub fn rhsScalarType(comptime BaseT: type, comptime RhsT: type) type { if (comptime isScalarType(RhsT)) return RhsT; if (comptime RhsT == comptime_int or RhsT == comptime_float or RhsT == BaseT) - return Scalar_(BaseT, Dimensions.init(.{}), Scales.init(.{})); + return Scalar(BaseT, .{}, .{}); @compileError( "rhs must be a Scalar, " ++ @typeName(BaseT) ++ ", comptime_int, or comptime_float; got " ++ @typeName(RhsT), @@ -40,7 +40,7 @@ pub fn rhsScalarType(comptime BaseT: type, comptime RhsT: type) type { /// Convert `rhs` to its normalised Scalar form (see `rhsScalarType`). pub inline fn toRhsScalar(comptime BaseT: type, rhs: anytype) rhsScalarType(BaseT, @TypeOf(rhs)) { if (comptime isScalarType(@TypeOf(rhs))) return rhs; - const DimLess = Scalar_(BaseT, Dimensions.init(.{}), Scales.init(.{})); + const DimLess = Scalar(BaseT, .{}, .{}); return DimLess{ .value = @as(BaseT, rhs) }; } @@ -49,11 +49,9 @@ pub inline fn toRhsScalar(comptime BaseT: type, rhs: anytype) rhsScalarType(Base /// A dimensioned scalar value. `T` is the numeric type, `d` the dimension exponents, `s` the SI scales. /// All dimension and unit tracking is resolved at comptime — zero runtime overhead. pub fn Scalar(comptime T: type, comptime d_opt: Dimensions.ArgOpts, comptime s_opt: Scales.ArgOpts) type { - return Scalar_(T, Dimensions.init(d_opt), Scales.init(s_opt)); -} - -pub fn Scalar_(comptime T: type, comptime d: Dimensions, comptime s: Scales) type { @setEvalBranchQuota(10_000_000); + const d = Dimensions.init(d_opt); + const s = Scales.init(s_opt); return struct { value: T, @@ -93,10 +91,10 @@ pub fn Scalar_(comptime T: type, comptime d: Dimensions, comptime s: Scales) typ /// Scales are auto-resolved to the finer of the two. /// `rhs` may be a Scalar, `T`, `comptime_int`, or `comptime_float` /// (bare numbers are treated as dimensionless). - pub inline fn add(self: Self, r: anytype) Scalar_( + pub inline fn add(self: Self, r: anytype) Scalar( T, - dims, - hlp.finerScales(Self, RhsT(@TypeOf(r))), + dims.argsOpt(), + hlp.finerScales(Self, RhsT(@TypeOf(r))).argsOpt(), ) { const rhs_s = rhs(r); const RhsType = @TypeOf(rhs_s); @@ -105,7 +103,7 @@ pub fn Scalar_(comptime T: type, comptime d: Dimensions, comptime s: Scales) typ if (comptime RhsType == Self) return .{ .value = self.value + rhs_s.value }; - const TargetType = Scalar_(T, dims, hlp.finerScales(Self, RhsType)); + const TargetType = Scalar(T, dims.argsOpt(), hlp.finerScales(Self, RhsType).argsOpt()); const lhs_val = if (comptime Self == TargetType) self.value else self.to(TargetType).value; const rhs_val = if (comptime RhsType == TargetType) rhs_s.value else rhs_s.to(TargetType).value; return .{ .value = lhs_val + rhs_val }; @@ -114,10 +112,10 @@ pub fn Scalar_(comptime T: type, comptime d: Dimensions, comptime s: Scales) typ /// Subtract two quantities. Dimensions must match — compile error otherwise. /// Scales are auto-resolved to the finer of the two. /// `rhs` may be a Scalar, `T`, `comptime_int`, or `comptime_float`. - pub inline fn sub(self: Self, r: anytype) Scalar_( + pub inline fn sub(self: Self, r: anytype) Scalar( T, - dims, - hlp.finerScales(Self, RhsT(@TypeOf(r))), + dims.argsOpt(), + hlp.finerScales(Self, RhsT(@TypeOf(r))).argsOpt(), ) { const rhs_s = rhs(r); const RhsType = @TypeOf(rhs_s); @@ -126,7 +124,7 @@ pub fn Scalar_(comptime T: type, comptime d: Dimensions, comptime s: Scales) typ if (comptime RhsType == Self) return .{ .value = self.value - rhs_s.value }; - const TargetType = Scalar_(T, dims, hlp.finerScales(Self, RhsType)); + const TargetType = Scalar(T, dims.argsOpt(), hlp.finerScales(Self, RhsType).argsOpt()); const lhs_val = if (comptime Self == TargetType) self.value else self.to(TargetType).value; const rhs_val = if (comptime RhsType == TargetType) rhs_s.value else rhs_s.to(TargetType).value; return .{ .value = lhs_val - rhs_val }; @@ -135,15 +133,15 @@ pub fn Scalar_(comptime T: type, comptime d: Dimensions, comptime s: Scales) typ /// Multiply two quantities. Dimension exponents are summed: `L¹ * T⁻¹ → L¹T⁻¹`. /// `rhs` may be a Scalar, `T`, `comptime_int`, or `comptime_float` /// (bare numbers are treated as dimensionless — dimensions pass through unchanged). - pub inline fn mulBy(self: Self, r: anytype) Scalar_( + pub inline fn mulBy(self: Self, r: anytype) Scalar( T, - dims.add(RhsT(@TypeOf(r)).dims), - hlp.finerScales(Self, RhsT(@TypeOf(r))), + dims.add(RhsT(@TypeOf(r)).dims).argsOpt(), + hlp.finerScales(Self, RhsT(@TypeOf(r))).argsOpt(), ) { const rhs_s = rhs(r); const RhsType = @TypeOf(rhs_s); - const SelfNorm = Scalar_(T, dims, hlp.finerScales(Self, RhsType)); - const RhsNorm = Scalar_(T, RhsType.dims, hlp.finerScales(Self, RhsType)); + const SelfNorm = Scalar(T, dims.argsOpt(), hlp.finerScales(Self, RhsType).argsOpt()); + const RhsNorm = Scalar(T, RhsType.dims.argsOpt(), hlp.finerScales(Self, RhsType).argsOpt()); if (comptime Self == SelfNorm and RhsType == RhsNorm) return .{ .value = self.value * rhs_s.value }; @@ -155,15 +153,15 @@ pub fn Scalar_(comptime T: type, comptime d: Dimensions, comptime s: Scales) typ /// Divide two quantities. Dimension exponents are subtracted: `L¹ / T¹ → L¹T⁻¹`. /// Integer types use truncating division. /// `rhs` may be a Scalar, `T`, `comptime_int`, or `comptime_float`. - pub inline fn divBy(self: Self, r: anytype) Scalar_( + pub inline fn divBy(self: Self, r: anytype) Scalar( T, - dims.sub(RhsT(@TypeOf(r)).dims), - hlp.finerScales(Self, RhsT(@TypeOf(r))), + dims.sub(RhsT(@TypeOf(r)).dims).argsOpt(), + hlp.finerScales(Self, RhsT(@TypeOf(r))).argsOpt(), ) { const rhs_s = rhs(r); const RhsType = @TypeOf(rhs_s); - const SelfNorm = Scalar_(T, dims, hlp.finerScales(Self, RhsType)); - const RhsNorm = Scalar_(T, RhsType.dims, hlp.finerScales(Self, RhsType)); + const SelfNorm = Scalar(T, dims.argsOpt(), hlp.finerScales(Self, RhsType).argsOpt()); + const RhsNorm = Scalar(T, RhsType.dims.argsOpt(), hlp.finerScales(Self, RhsType).argsOpt()); const lhs_val = if (comptime Self == SelfNorm) self.value else self.to(SelfNorm).value; const rhs_val = if (comptime RhsType == RhsNorm) rhs_s.value else rhs_s.to(RhsNorm).value; if (comptime @typeInfo(T) == .int) { @@ -188,10 +186,10 @@ pub fn Scalar_(comptime T: type, comptime d: Dimensions, comptime s: Scales) typ /// Raises the quantity to a compile-time integer exponent. /// Dimension exponents are multiplied by the exponent: `(L²)³ → L⁶`. - pub inline fn pow(self: Self, comptime exp: comptime_int) Scalar_( + pub inline fn pow(self: Self, comptime exp: comptime_int) Scalar( T, - dims.scale(exp), - s, + dims.scale(exp).argsOpt(), + scales.argsOpt(), ) { if (comptime @typeInfo(T) == .int) return .{ .value = std.math.powi(T, self.value, exp) catch @panic("Integer overflow in pow") } @@ -199,10 +197,10 @@ pub fn Scalar_(comptime T: type, comptime d: Dimensions, comptime s: Scales) typ return .{ .value = std.math.pow(T, self.value, @as(T, @floatFromInt(exp))) }; } - pub inline fn sqrt(self: Self) Scalar_( + pub inline fn sqrt(self: Self) Scalar( T, - dims.div(2), - s, + dims.div(2).argsOpt(), + scales.argsOpt(), ) { if (comptime !dims.isSquare()) // Check if all exponents are divisible by 2 @compileError("Cannot take sqrt of " ++ dims.str() ++ ": exponents must be even."); @@ -279,7 +277,7 @@ pub fn Scalar_(comptime T: type, comptime d: Dimensions, comptime s: Scales) typ if (comptime RhsType == Self) return self.value == rhs_s.value; - const TargetType = Scalar_(T, dims, hlp.finerScales(Self, RhsType)); + const TargetType = Scalar(T, dims.argsOpt(), hlp.finerScales(Self, RhsType).argsOpt()); const lhs_val = if (comptime Self == TargetType) self.value else self.to(TargetType).value; const rhs_val = if (comptime RhsType == TargetType) rhs_s.value else rhs_s.to(TargetType).value; return lhs_val == rhs_val; @@ -296,7 +294,7 @@ pub fn Scalar_(comptime T: type, comptime d: Dimensions, comptime s: Scales) typ if (comptime RhsType == Self) return self.value != rhs_s.value; - const TargetType = Scalar_(T, dims, hlp.finerScales(Self, RhsType)); + const TargetType = Scalar(T, dims.argsOpt(), hlp.finerScales(Self, RhsType).argsOpt()); const lhs_val = if (comptime Self == TargetType) self.value else self.to(TargetType).value; const rhs_val = if (comptime RhsType == TargetType) rhs_s.value else rhs_s.to(TargetType).value; return lhs_val != rhs_val; @@ -313,7 +311,7 @@ pub fn Scalar_(comptime T: type, comptime d: Dimensions, comptime s: Scales) typ if (comptime RhsType == Self) return self.value > rhs_s.value; - const TargetType = Scalar_(T, dims, hlp.finerScales(Self, RhsType)); + const TargetType = Scalar(T, dims.argsOpt(), hlp.finerScales(Self, RhsType).argsOpt()); const lhs_val = if (comptime Self == TargetType) self.value else self.to(TargetType).value; const rhs_val = if (comptime RhsType == TargetType) rhs_s.value else rhs_s.to(TargetType).value; return lhs_val > rhs_val; @@ -330,7 +328,7 @@ pub fn Scalar_(comptime T: type, comptime d: Dimensions, comptime s: Scales) typ if (comptime RhsType == Self) return self.value >= rhs_s.value; - const TargetType = Scalar_(T, dims, hlp.finerScales(Self, RhsType)); + const TargetType = Scalar(T, dims.argsOpt(), hlp.finerScales(Self, RhsType).argsOpt()); const lhs_val = if (comptime Self == TargetType) self.value else self.to(TargetType).value; const rhs_val = if (comptime RhsType == TargetType) rhs_s.value else rhs_s.to(TargetType).value; return lhs_val >= rhs_val; @@ -347,7 +345,7 @@ pub fn Scalar_(comptime T: type, comptime d: Dimensions, comptime s: Scales) typ if (comptime RhsType == Self) return self.value < rhs_s.value; - const TargetType = Scalar_(T, dims, hlp.finerScales(Self, RhsType)); + const TargetType = Scalar(T, dims.argsOpt(), hlp.finerScales(Self, RhsType).argsOpt()); const lhs_val = if (comptime Self == TargetType) self.value else self.to(TargetType).value; const rhs_val = if (comptime RhsType == TargetType) rhs_s.value else rhs_s.to(TargetType).value; return lhs_val < rhs_val; @@ -364,7 +362,7 @@ pub fn Scalar_(comptime T: type, comptime d: Dimensions, comptime s: Scales) typ if (comptime RhsType == Self) return self.value <= rhs_s.value; - const TargetType = Scalar_(T, dims, hlp.finerScales(Self, RhsType)); + const TargetType = Scalar(T, dims.argsOpt(), hlp.finerScales(Self, RhsType).argsOpt()); const lhs_val = if (comptime Self == TargetType) self.value else self.to(TargetType).value; const rhs_val = if (comptime RhsType == TargetType) rhs_s.value else rhs_s.to(TargetType).value; return lhs_val <= rhs_val; diff --git a/src/Scales.zig b/src/Scales.zig index f300e28..2544315 100644 --- a/src/Scales.zig +++ b/src/Scales.zig @@ -69,14 +69,14 @@ pub const UnitScale = enum(isize) { }; /// Maps each SI base dimension to its `UnitScale`. Stored and resolved entirely at comptime. -const Scales = @This(); +const Self = @This(); data: std.EnumArray(Dimension, UnitScale), /// Create a `Scales` from a struct literal, e.g. `.{ .L = .k, .T = .hour }`. /// Unspecified dimensions default to `.none` (factor 1). -pub fn init(comptime init_val: ArgOpts) Scales { - comptime var s = Scales{ .data = std.EnumArray(Dimension, UnitScale).initFill(.none) }; +pub fn init(comptime init_val: ArgOpts) Self { + comptime var s = Self{ .data = std.EnumArray(Dimension, UnitScale).initFill(.none) }; inline for (std.meta.fields(@TypeOf(init_val))) |f| { if (comptime hlp.isInt(@TypeOf(@field(init_val, f.name)))) s.data.set(@field(Dimension, f.name), @enumFromInt(@field(init_val, f.name))) @@ -86,21 +86,28 @@ pub fn init(comptime init_val: ArgOpts) Scales { return s; } -pub fn initFill(comptime val: UnitScale) Scales { +pub fn initFill(comptime val: UnitScale) Self { return comptime .{ .data = std.EnumArray(Dimension, UnitScale).initFill(val) }; } -pub fn get(comptime self: Scales, comptime key: Dimension) UnitScale { +pub fn get(comptime self: Self, comptime key: Dimension) UnitScale { return comptime self.data.get(key); } -pub fn set(comptime self: *Scales, comptime key: Dimension, comptime val: UnitScale) void { +pub fn set(comptime self: *Self, comptime key: Dimension, comptime val: UnitScale) void { comptime self.data.set(key, val); } +pub fn argsOpt(self: Self) ArgOpts { + var args: ArgOpts = undefined; + inline for (std.enums.values(Dimension)) |d| + @field(args, @tagName(d)) = self.get(d); + return args; +} + /// Compute the combined scale factor for a given dimension signature. /// Each dimension's prefix is raised to its exponent and multiplied together. -pub inline fn getFactor(comptime s: Scales, comptime d: Dimensions) comptime_float { +pub inline fn getFactor(comptime s: Self, comptime d: Dimensions) comptime_float { var factor: f64 = 1.0; for (std.enums.values(Dimension)) |dim| { const power = comptime d.get(dim); diff --git a/src/Vector.zig b/src/Vector.zig index 54657b2..94e48e4 100644 --- a/src/Vector.zig +++ b/src/Vector.zig @@ -2,7 +2,6 @@ const std = @import("std"); const hlp = @import("helper.zig"); const Scalar = @import("Scalar.zig").Scalar; -const Scalar_ = @import("Scalar.zig").Scalar_; const Scales = @import("Scales.zig"); const UnitScale = Scales.UnitScale; const Dimensions = @import("Dimensions.zig"); @@ -33,13 +32,17 @@ pub fn Vector(comptime len: usize, comptime Q: type) type { } /// Element-wise addition. Dimensions must match; scales resolve to the finer of the two. - pub inline fn add(self: Self, rhs: anytype) Vector(len, Scalar_( + pub inline fn add(self: Self, rhs: anytype) Vector(len, Scalar( T, - dims, - hlp.finerScales(Self, @TypeOf(rhs)), + dims.argsOpt(), + hlp.finerScales(Self, @TypeOf(rhs)).argsOpt(), )) { const Tr = @TypeOf(rhs); - var res: Vector(len, Scalar_(T, d, hlp.finerScales(Self, @TypeOf(rhs)))) = undefined; + var res: Vector(len, Scalar( + T, + dims.argsOpt(), + hlp.finerScales(Self, @TypeOf(rhs)).argsOpt(), + )) = undefined; inline for (self.data, 0..) |v, i| { const q = (Q{ .value = v }).add(Tr.ScalarType{ .value = rhs.data[i] }); res.data[i] = q.value; @@ -47,13 +50,17 @@ pub fn Vector(comptime len: usize, comptime Q: type) type { return res; } /// Element-wise subtraction. Dimensions must match; scales resolve to the finer of the two. - pub inline fn sub(self: Self, rhs: anytype) Vector(len, Scalar_( + pub inline fn sub(self: Self, rhs: anytype) Vector(len, Scalar( T, - dims, - hlp.finerScales(Self, @TypeOf(rhs)), + dims.argsOpt(), + hlp.finerScales(Self, @TypeOf(rhs)).argsOpt(), )) { const Tr = @TypeOf(rhs); - var res: Vector(len, Scalar_(T, d, hlp.finerScales(Self, @TypeOf(rhs)))) = undefined; + var res: Vector(len, Scalar( + T, + dims.argsOpt(), + hlp.finerScales(Self, @TypeOf(rhs)).argsOpt(), + )) = undefined; inline for (self.data, 0..) |v, i| { const q = (Q{ .value = v }).sub(Tr.ScalarType{ .value = rhs.data[i] }); res.data[i] = q.value; @@ -65,13 +72,17 @@ pub fn Vector(comptime len: usize, comptime Q: type) type { pub inline fn divBy( self: Self, rhs: anytype, - ) Vector(len, Scalar_( + ) Vector(len, Scalar( T, - dims.sub(@TypeOf(rhs).dims), - hlp.finerScales(Self, @TypeOf(rhs)), + dims.sub(@TypeOf(rhs).dims).argsOpt(), + hlp.finerScales(Self, @TypeOf(rhs)).argsOpt(), )) { const Tr = @TypeOf(rhs); - var res: Vector(len, Scalar_(T, d.sub(Tr.dims), hlp.finerScales(Self, @TypeOf(rhs)))) = undefined; + var res: Vector(len, Scalar( + T, + d.sub(Tr.dims).argsOpt(), + hlp.finerScales(Self, @TypeOf(rhs)).argsOpt(), + )) = undefined; inline for (self.data, 0..) |v, i| { const q = (Q{ .value = v }).divBy(Tr.ScalarType{ .value = rhs.data[i] }); res.data[i] = q.value; @@ -83,13 +94,17 @@ pub fn Vector(comptime len: usize, comptime Q: type) type { pub inline fn mulBy( self: Self, rhs: anytype, - ) Vector(len, Scalar_( + ) Vector(len, Scalar( T, - dims.add(@TypeOf(rhs).dims), - hlp.finerScales(Self, @TypeOf(rhs)), + dims.add(@TypeOf(rhs).dims).argsOpt(), + hlp.finerScales(Self, @TypeOf(rhs)).argsOpt(), )) { const Tr = @TypeOf(rhs); - var res: Vector(len, Scalar_(T, d.add(Tr.dims), hlp.finerScales(Self, @TypeOf(rhs)))) = undefined; + var res: Vector(len, Scalar( + T, + dims.add(Tr.dims).argsOpt(), + hlp.finerScales(Self, @TypeOf(rhs)).argsOpt(), + )) = undefined; inline for (self.data, 0..) |v, i| { const q = (Q{ .value = v }).mulBy(Tr.ScalarType{ .value = rhs.data[i] }); res.data[i] = q.value; @@ -101,12 +116,16 @@ pub fn Vector(comptime len: usize, comptime Q: type) type { pub inline fn divByScalar( self: Self, scalar: anytype, - ) Vector(len, Scalar_( + ) Vector(len, Scalar( T, - dims.sub(@TypeOf(scalar).dims), - hlp.finerScales(Self, @TypeOf(scalar)), + dims.sub(@TypeOf(scalar).dims).argsOpt(), + hlp.finerScales(Self, @TypeOf(scalar)).argsOpt(), )) { - var res: Vector(len, Scalar_(T, d.sub(@TypeOf(scalar).dims), hlp.finerScales(Self, @TypeOf(scalar)))) = undefined; + var res: Vector(len, Scalar( + T, + dims.sub(@TypeOf(scalar).dims).argsOpt(), + hlp.finerScales(Self, @TypeOf(scalar)).argsOpt(), + )) = undefined; inline for (self.data, 0..) |v, i| { const q = Q{ .value = v }; res.data[i] = q.divBy(scalar).value; @@ -118,12 +137,16 @@ pub fn Vector(comptime len: usize, comptime Q: type) type { pub inline fn mulByScalar( self: Self, scalar: anytype, - ) Vector(len, Scalar_( + ) Vector(len, Scalar( T, - dims.add(@TypeOf(scalar).dims), - hlp.finerScales(Self, @TypeOf(scalar)), + dims.add(@TypeOf(scalar).dims).argsOpt(), + hlp.finerScales(Self, @TypeOf(scalar)).argsOpt(), )) { - var res: Vector(len, Scalar_(T, d.add(@TypeOf(scalar).dims), hlp.finerScales(Self, @TypeOf(scalar)))) = undefined; + var res: Vector(len, Scalar( + T, + dims.add(@TypeOf(scalar).dims).argsOpt(), + hlp.finerScales(Self, @TypeOf(scalar)).argsOpt(), + )) = undefined; inline for (self.data, 0..) |v, i| { const q = Q{ .value = v }; res.data[i] = q.mulBy(scalar).value; @@ -133,10 +156,10 @@ pub fn Vector(comptime len: usize, comptime Q: type) type { /// Standard dot product. Dimensions are summed (e.g., Force * Distance = Energy). /// Returns a Scalar type with the combined dimensions and finest scale. - pub inline fn dot(self: Self, rhs: anytype) Scalar_( + pub inline fn dot(self: Self, rhs: anytype) Scalar( T, - dims.add(@TypeOf(rhs).dims), - hlp.finerScales(Self, @TypeOf(rhs)), + dims.add(@TypeOf(rhs).dims).argsOpt(), + hlp.finerScales(Self, @TypeOf(rhs)).argsOpt(), ) { const Tr = @TypeOf(rhs); @@ -151,16 +174,16 @@ pub fn Vector(comptime len: usize, comptime Q: type) type { /// 3D Cross product. Dimensions are summed. /// Only valid for vectors of length 3. - pub inline fn cross(self: Self, rhs: anytype) Vector(3, Scalar_( + pub inline fn cross(self: Self, rhs: anytype) Vector(3, Scalar( T, - dims.add(@TypeOf(rhs).dims), - hlp.finerScales(Self, @TypeOf(rhs)), + dims.add(@TypeOf(rhs).dims).argsOpt(), + hlp.finerScales(Self, @TypeOf(rhs)).argsOpt(), )) { if (comptime len != 3) @compileError("Cross product is only defined for Vector(3, ...)"); const Tr = @TypeOf(rhs); - const ResScalar = Scalar_(T, d.add(Tr.dims), hlp.finerScales(Self, Tr)); + const ResScalar = Scalar(T, d.add(Tr.dims).argsOpt(), hlp.finerScales(Self, Tr).argsOpt()); const ResVec = Vector(3, ResScalar); // Calculation: [y1*z2 - z1*y2, z1*x2 - x1*z2, x1*y2 - y1*x2] @@ -203,10 +226,10 @@ pub fn Vector(comptime len: usize, comptime Q: type) type { /// Multiplies all components of the vector together. /// Resulting dimensions are (Original Dims * len). - pub inline fn product(self: Self) Scalar_( + pub inline fn product(self: Self) Scalar( T, - dims.scale(len), - scales, + dims.scale(len).argsOpt(), + scales.argsOpt(), ) { var res_val: T = 1; inline for (self.data) |v| @@ -216,12 +239,15 @@ pub fn Vector(comptime len: usize, comptime Q: type) type { /// Raises every component to a compile-time integer power. /// Dimensions are scaled by the exponent. - pub inline fn pow(self: Self, comptime exp: comptime_int) Vector(len, Scalar_( - T, - dims.scale(exp), - scales, - )) { - const ResScalar = Scalar_(T, dims.scale(exp), s); + pub inline fn pow(self: Self, comptime exp: comptime_int) Vector( + len, + Scalar( + T, + dims.scale(exp).argsOpt(), + scales.argsOpt(), + ), + ) { + const ResScalar = Scalar(T, dims.scale(exp).argsOpt(), scales.argsOpt()); var res: Vector(len, ResScalar) = undefined; inline for (self.data, 0..) |v, i| { const q = Q{ .value = v };