From 86841318f248ef74118227ddb623926a9bde4710 Mon Sep 17 00:00:00 2001 From: adrien Date: Wed, 22 Apr 2026 10:58:14 +0200 Subject: [PATCH] Added some doc comments --- src/Dimensions.zig | 9 +++++++++ src/Scalar.zig | 27 ++++++++++++++++++++++++++- src/Scales.zig | 8 ++++++++ src/Vector.zig | 12 +++++++++++- 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/Dimensions.zig b/src/Dimensions.zig index d691a79..e5805ec 100644 --- a/src/Dimensions.zig +++ b/src/Dimensions.zig @@ -29,10 +29,16 @@ pub const Dimension = enum { } }; +// --------- Dimensions struct --------- + +/// Holds the exponent of each SI base dimension for a given quantity (e.g. velocity = L¹T⁻¹). +/// All values are `comptime_int` — no runtime storage. const Self = @This(); data: std.EnumArray(Dimension, comptime_int), +/// Create a `Dimensions` from an anonymous struct literal, e.g. `.{ .L = 1, .T = -1 }`. +/// Unspecified dimensions default to 0. pub fn init(comptime init_val: anytype) Self { var s = Self{ .data = std.EnumArray(Dimension, comptime_int).initFill(0) }; inline for (std.meta.fields(@TypeOf(init_val))) |f| @@ -52,6 +58,7 @@ pub fn set(comptime self: *Self, comptime key: Dimension, comptime val: i8) void self.data.set(key, val); } +/// 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| @@ -59,6 +66,7 @@ pub fn add(comptime a: Self, comptime b: Self) Self { return result; } +/// Subtract exponents component-wise. Used internally by `divBy`. pub fn sub(comptime a: Self, comptime b: Self) Self { @setEvalBranchQuota(10_000); var result = Self.initFill(0); @@ -67,6 +75,7 @@ pub fn sub(comptime a: Self, comptime b: Self) Self { return result; } +/// Returns true if every dimension exponent is equal. Used to enforce type compatibility in `add`, `sub`, `to`. pub fn eql(comptime a: Self, comptime b: Self) bool { inline for (std.enums.values(Dimension)) |d| if (a.get(d) != b.get(d)) return false; diff --git a/src/Scalar.zig b/src/Scalar.zig index 56b950d..d40607f 100644 --- a/src/Scalar.zig +++ b/src/Scalar.zig @@ -18,18 +18,29 @@ const Dimension = Dimensions.Dimension; // - pow: Scalar power another // - log: Scalar log another +/// 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: Dimensions, comptime s: Scales) type { @setEvalBranchQuota(10_000_000); return struct { value: T, const Self = @This(); + + /// Type of Vector(3, Self) pub const Vec3: type = Vector(3, Self); + + /// Type of underline value, mostly use for Vector pub const ValueType: type = T; + /// Dimensions of this type pub const dims: Dimensions = d; + + /// Scales of this type pub const scales = s; + /// Add two quantities. Dimensions must match — compile error otherwise. + /// Scales are auto-resolved to the finer of the two. pub inline fn add(self: Self, rhs: anytype) Scalar( T, dims, @@ -47,6 +58,8 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type return .{ .value = lhs_val + rhs_val }; } + /// Subtract two quantities. Dimensions must match — compile error otherwise. + /// Scales are auto-resolved to the finer of the two. pub inline fn sub(self: Self, rhs: anytype) Scalar( T, dims, @@ -64,6 +77,7 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type return .{ .value = lhs_val - rhs_val }; } + /// Multiply two quantities. Dimension exponents are summed: `L¹ * T⁻¹ → L¹T⁻¹`. pub inline fn mulBy(self: Self, rhs: anytype) Scalar( T, dims.add(@TypeOf(rhs).dims), @@ -80,6 +94,8 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type return .{ .value = lhs_val * rhs_val }; } + /// Divide two quantities. Dimension exponents are subtracted: `L¹ / T¹ → L¹T⁻¹`. + /// Integer types use truncating division. pub inline fn divBy(self: Self, rhs: anytype) Scalar( T, dims.sub(@TypeOf(rhs).dims), @@ -97,6 +113,8 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type } } + /// Convert to a compatible unit type. The scale ratio is computed at comptime. + /// Compile error if dimensions don't match. pub inline 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()); @@ -138,10 +156,17 @@ pub fn Scalar(comptime T: type, comptime d: Dimensions, comptime s: Scales) type } } - pub fn Vec(self: Self, comptime len: comptime_int) Vector(len, Self) { + /// Return a `Vector(len, Self)` type. + pub fn Vec(_: Self, comptime len: comptime_int) type { + return Vector(len, Self); + } + + /// Return a `Vector(len, Self)` with all components set to this value. + pub fn vec(self: Self, comptime len: comptime_int) Vector(len, Self) { return Vector(len, Self).initDefault(self.value); } + /// Shorthand for `Vec(3)` — wrap this value into a 3-component vector. pub fn vec3(self: Self) Vec3 { return Vec3.initDefault(self.value); } diff --git a/src/Scales.zig b/src/Scales.zig index 3799ee3..53f74a0 100644 --- a/src/Scales.zig +++ b/src/Scales.zig @@ -3,6 +3,9 @@ const hlp = @import("helper.zig"); const Dimensions = @import("Dimensions.zig"); const Dimension = @import("Dimensions.zig").Dimension; +/// SI prefix (pico…peta) plus time-unit aliases (min, hour, year). +/// The integer value encodes the exponent for SI prefixes (e.g. `k = 3` → 10³), +/// and the literal factor for time units (e.g. `hour = 3600`). pub const UnitScale = enum(isize) { P = 15, T = 12, @@ -54,10 +57,13 @@ pub const UnitScale = enum(isize) { } }; +/// Maps each SI base dimension to its `UnitScale`. Stored and resolved entirely at comptime. const Scales = @This(); data: std.EnumArray(Dimension, UnitScale), +/// Create a `Scales` from an anonymous struct literal, e.g. `.{ .L = .k, .T = .hour }`. +/// Unspecified dimensions default to `.none` (factor 1). pub fn init(comptime init_val: anytype) Scales { comptime var s = Scales{ .data = std.EnumArray(Dimension, UnitScale).initFill(.none) }; inline for (std.meta.fields(@TypeOf(init_val))) |f| { @@ -81,6 +87,8 @@ pub fn set(comptime self: *Scales, comptime key: Dimension, comptime val: UnitSc comptime self.data.set(key, val); } +/// 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 { comptime var factor: f64 = 1.0; inline for (std.enums.values(Dimension)) |dim| { diff --git a/src/Vector.zig b/src/Vector.zig index 727f922..8b0e6d1 100644 --- a/src/Vector.zig +++ b/src/Vector.zig @@ -7,6 +7,7 @@ const UnitScale = Scales.UnitScale; const Dimensions = @import("Dimensions.zig"); const Dimension = Dimensions.Dimension; +/// A fixed-size array of `len` elements sharing the same dimension and scale as scalar type `Q`. pub fn Vector(comptime len: usize, comptime Q: type) type { const T = Q.ValueType; const d: Dimensions = Q.dims; @@ -30,6 +31,7 @@ pub fn Vector(comptime len: usize, comptime Q: type) type { return .{ .data = data }; } + /// 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( T, dims, @@ -43,7 +45,7 @@ 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( T, dims, @@ -58,6 +60,7 @@ pub fn Vector(comptime len: usize, comptime Q: type) type { return res; } + /// Element-wise division. Dimension exponents are subtracted per component. pub inline fn divBy( self: Self, rhs: anytype, @@ -75,6 +78,7 @@ pub fn Vector(comptime len: usize, comptime Q: type) type { return res; } + /// Element-wise multiplication. Dimension exponents are summed per component. pub inline fn mulBy( self: Self, rhs: anytype, @@ -92,6 +96,7 @@ pub fn Vector(comptime len: usize, comptime Q: type) type { return res; } + /// Divide every component by a single scalar. Dimensions are subtracted (e.g. position / time → velocity). pub inline fn divByScalar( self: Self, scalar: anytype, @@ -108,6 +113,7 @@ pub fn Vector(comptime len: usize, comptime Q: type) type { return res; } + /// Multiply every component by a single scalar. Dimensions are summed. pub inline fn mulByScalar( self: Self, scalar: anytype, @@ -124,6 +130,7 @@ pub fn Vector(comptime len: usize, comptime Q: type) type { return res; } + /// Negate all components. Dimensions are preserved. pub fn negate(self: Self) Self { var res: Self = undefined; inline for (self.data, 0..) |v, i| @@ -131,6 +138,7 @@ pub fn Vector(comptime len: usize, comptime Q: type) type { return res; } + /// Convert all components to a compatible scalar type. Compile error on dimension mismatch. pub inline fn to(self: Self, comptime DestQ: type) Vector(len, DestQ) { var res: Vector(len, DestQ) = undefined; inline for (self.data, 0..) |v, i| @@ -138,6 +146,7 @@ pub fn Vector(comptime len: usize, comptime Q: type) type { return res; } + /// Sum of squared components. Cheaper than `length` — use for comparisons. pub inline fn lengthSqr(self: Self) T { var sum: T = 0; inline for (self.data) |v| @@ -145,6 +154,7 @@ pub fn Vector(comptime len: usize, comptime Q: type) type { return sum; } + /// Euclidean length. Integer types use integer sqrt (truncated). pub inline fn length(self: Self) T { const len_sq = self.lengthSqr();