Compare commits

..

No commits in common. "b02665fe8978838d291762bf768c554596c00401" and "7b038dd2a535028c76755aedb42e0e5e93f63f67" have entirely different histories.

2 changed files with 21 additions and 35 deletions

View File

@ -8,7 +8,6 @@ const Dimensions = @import("Dimensions.zig");
const Dimension = Dimensions.Dimension;
pub fn Quantity(comptime T: type, comptime d: Dimensions, comptime s: Scales) type {
@setEvalBranchQuota(100_000);
return struct {
value: T,
@ -19,76 +18,62 @@ pub fn Quantity(comptime T: type, comptime d: Dimensions, comptime s: Scales) ty
pub const dims: Dimensions = d;
pub const scales = s;
pub inline fn add(self: Self, rhs: anytype) Quantity(
pub fn add(self: Self, rhs: anytype) Quantity(
T,
dims,
scales.min(@TypeOf(rhs).scales),
) {
if (comptime !dims.eql(@TypeOf(rhs).dims))
@compileError("Dimension mismatch in add: " ++ dims.str() ++ " vs " ++ @TypeOf(rhs).dims.str());
if (comptime @TypeOf(rhs) == Self)
return .{ .value = self.value + rhs.value };
const TargetType = Quantity(T, dims, scales.min(@TypeOf(rhs).scales));
const lhs_val = if (comptime @TypeOf(self) == TargetType) self.value else self.to(TargetType).value;
const rhs_val = if (comptime @TypeOf(rhs) == TargetType) rhs.value else rhs.to(TargetType).value;
const lhs_converted = self.to(TargetType);
const rhs_converted = rhs.to(TargetType);
return .{ .value = lhs_val + rhs_val };
return .{ .value = lhs_converted.value + rhs_converted.value };
}
pub inline fn sub(self: Self, rhs: anytype) Quantity(
pub fn sub(self: Self, rhs: anytype) Quantity(
T,
dims,
scales.min(@TypeOf(rhs).scales),
) {
if (comptime !dims.eql(@TypeOf(rhs).dims))
@compileError("Dimension mismatch in sub: " ++ dims.str() ++ " vs " ++ @TypeOf(rhs).dims.str());
if (comptime @TypeOf(rhs) == Self)
return .{ .value = self.value - rhs.value };
const TargetType = Quantity(T, dims, scales.min(@TypeOf(rhs).scales));
const lhs_val = if (comptime @TypeOf(self) == TargetType) self.value else self.to(TargetType).value;
const rhs_val = if (comptime @TypeOf(rhs) == TargetType) rhs.value else rhs.to(TargetType).value;
const lhs_converted = self.to(TargetType);
const rhs_converted = rhs.to(TargetType);
return .{ .value = lhs_val - rhs_val };
return .{ .value = lhs_converted.value - rhs_converted.value };
}
pub inline fn mulBy(self: Self, rhs: anytype) Quantity(
pub fn mulBy(self: Self, rhs: anytype) Quantity(
T,
dims.add(@TypeOf(rhs).dims),
scales.min(@TypeOf(rhs).scales),
) {
const RhsType = @TypeOf(rhs);
const SelfNorm = Quantity(T, dims, scales.min(RhsType.scales));
const RhsNorm = Quantity(T, RhsType.dims, scales.min(RhsType.scales));
// Only convert the side(s) that actually need it
const lhs_val = if (comptime Self == SelfNorm) self.value else self.to(SelfNorm).value;
const rhs_val = if (comptime RhsType == RhsNorm) rhs.value else rhs.to(RhsNorm).value;
return .{ .value = lhs_val * rhs_val };
const self_ = self.to(Quantity(T, dims, scales.min(@TypeOf(rhs).scales)));
const rhs_ = rhs.to(Quantity(T, @TypeOf(rhs).dims, scales.min(@TypeOf(rhs).scales)));
return .{ .value = self_.value * rhs_.value };
}
pub inline fn divBy(self: Self, rhs: anytype) Quantity(
T,
dims.sub(@TypeOf(rhs).dims),
scales.min(@TypeOf(rhs).scales),
) {
const RhsType = @TypeOf(rhs);
const SelfNorm = Quantity(T, dims, scales.min(RhsType.scales));
const RhsNorm = Quantity(T, RhsType.dims, scales.min(RhsType.scales));
const lhs_val = if (comptime Self == SelfNorm) self.value else self.to(SelfNorm).value;
const rhs_val = if (comptime RhsType == RhsNorm) rhs.value else rhs.to(RhsNorm).value;
pub fn divBy(self: Self, rhs: anytype) Quantity(T, dims.sub(@TypeOf(rhs).dims), scales.min(@TypeOf(rhs).scales)) {
const self_ = self.to(Quantity(T, dims, scales.min(@TypeOf(rhs).scales)));
const rhs_ = rhs.to(Quantity(T, @TypeOf(rhs).dims, scales.min(@TypeOf(rhs).scales)));
if (comptime @typeInfo(T) == .int) {
return .{ .value = @divTrunc(lhs_val, rhs_val) };
return .{ .value = @divTrunc(self_.value, rhs_.value) };
} else {
return .{ .value = lhs_val / rhs_val };
return .{ .value = self_.value / rhs_.value };
}
}
pub inline fn scale(self: Self, sc: T) Self {
pub fn scale(self: Self, sc: T) Self {
return .{ .value = self.value * sc };
}
pub inline fn to(self: Self, comptime Dest: type) Dest {
pub fn to(self: Self, comptime Dest: type) Dest {
if (comptime !dims.eql(Dest.dims))
@compileError("Dimension mismatch in to: " ++ dims.str() ++ " vs " ++ Dest.dims.str());
if (comptime @TypeOf(self) == Dest)

View File

@ -82,6 +82,7 @@ pub fn set(comptime self: *Scales, comptime key: Dimension, comptime val: UnitSc
}
pub fn min(comptime s1: Scales, comptime s2: Scales) Scales {
@setEvalBranchQuota(10_000);
comptime var out = Scales.initFill(.none);
inline for (std.enums.values(Dimension)) |dim|
out.set(dim, if (s1.get(dim).getFactorInt() > s2.get(dim).getFactorInt()) s2.get(dim) else s1.get(dim));