Tehforsch / diman

Define rust compile time unit systems using const generics
52 stars 2 forks source link

Reference arithmetic #53

Closed Tehforsch closed 8 months ago

Tehforsch commented 8 months ago

Solves #50, so that

    let velocity = [Velocity::meters_per_second(5.0); 3];
    let energy = 0.5 * velocity.iter().map(|v| v * v).sum::<SpecificEnergy>();

compiles fine.

TODO: Fix the impls for glam vecs.

For now, I implemented Add<&Quantity<S, _>> for Quantity<S, _> by requiring S: Copy and wrote Quantity(self.0 + rhs.0). Another alternative would have been to require S: Add<&'S>, so that the types internal implementation can take care of it and I can simply write Quantity(self.0 + &rhs.0).

I went with the first option, because the only non-primitive storage type that is currently supported are glams vectors which are Copy and do not implement Vec3: Add<&Vec3>. In the future, this might have to be expanded.

I took the opportunity to refactor the code that generates the trait impls. Previously, a lot of manual work went into writing the impl for a new trait, since I would basically have to specify all the individual part of the impl almost manually.

Now, a given trait impl is represented by its name (Add, Sub, AddAssign, ... PartialEq) and its two operands. For each operand, the trait knows whether

  1. It's a quantity, a dimensionless quantity or the storage type itself
  2. Given by reference or value
  3. Its storage type is concrete (f32, ...) or generic.

Based on this information, the code then generates the entire impl. This is quite finicky, since the traits are all very similar but still subtly different in each concrete case. However, the code I ended up with now seems to be pretty robust.

Current list of implemented traits with just f32 and f64 enabled (LHS / RHS / S stand for generic storage types):

Add (Quantity LHS) (Quantity RHS)
Add (Quantity LHS) (&Quantity RHS)
Add (&Quantity LHS) (Quantity RHS)
Add (&Quantity LHS) (&Quantity RHS)
Sub (Quantity LHS) (Quantity RHS)
Sub (Quantity LHS) (&Quantity RHS)
Sub (&Quantity LHS) (Quantity RHS)
Sub (&Quantity LHS) (&Quantity RHS)
Mul (Quantity LHS) (Quantity RHS)
Mul (Quantity LHS) (&Quantity RHS)
Mul (&Quantity LHS) (Quantity RHS)
Mul (&Quantity LHS) (&Quantity RHS)
Div (Quantity LHS) (Quantity RHS)
Div (Quantity LHS) (&Quantity RHS)
Div (&Quantity LHS) (Quantity RHS)
Div (&Quantity LHS) (&Quantity RHS)
AddAssign (Quantity LHS) (Quantity RHS)
AddAssign (Quantity LHS) (&Quantity RHS)
AddAssign (& mutQuantity LHS) (Quantity RHS)
AddAssign (& mutQuantity LHS) (&Quantity RHS)
SubAssign (Quantity LHS) (Quantity RHS)
SubAssign (Quantity LHS) (&Quantity RHS)
SubAssign (& mutQuantity LHS) (Quantity RHS)
SubAssign (& mutQuantity LHS) (&Quantity RHS)
MulAssign (Quantity LHS) (Dimensionless RHS)
MulAssign (Quantity LHS) (&Dimensionless RHS)
MulAssign (& mutQuantity LHS) (Dimensionless RHS)
MulAssign (& mutQuantity LHS) (&Dimensionless RHS)
DivAssign (Quantity LHS) (Dimensionless RHS)
DivAssign (Quantity LHS) (&Dimensionless RHS)
DivAssign (& mutQuantity LHS) (Dimensionless RHS)
DivAssign (& mutQuantity LHS) (&Dimensionless RHS)
PartialOrd (Quantity LHS) (Quantity RHS)
PartialOrd (Quantity LHS) (&Quantity RHS)
PartialOrd (&Quantity LHS) (Quantity RHS)
PartialEq (Quantity LHS) (Quantity RHS)
PartialEq (Quantity LHS) (&Quantity RHS)
PartialEq (&Quantity LHS) (Quantity RHS)
Add (Dimensionless S) ( S)
Add (Dimensionless S) (& S)
Add (&Dimensionless S) ( S)
Add (&Dimensionless S) (& S)
Sub (Dimensionless S) ( S)
Sub (Dimensionless S) (& S)
Sub (&Dimensionless S) ( S)
Sub (&Dimensionless S) (& S)
AddAssign (Dimensionless S) ( S)
AddAssign (Dimensionless S) (& S)
AddAssign (& mutDimensionless S) ( S)
AddAssign (& mutDimensionless S) (& S)
SubAssign (Dimensionless S) ( S)
SubAssign (Dimensionless S) (& S)
SubAssign (& mutDimensionless S) ( S)
SubAssign (& mutDimensionless S) (& S)
Add (Storage f32) (Dimensionless f32)
Add (Storage f32) (&Dimensionless f32)
Add (&Storage f32) (Dimensionless f32)
Add (&Storage f32) (&Dimensionless f32)
Sub (Storage f32) (Dimensionless f32)
Sub (Storage f32) (&Dimensionless f32)
Sub (&Storage f32) (Dimensionless f32)
Sub (&Storage f32) (&Dimensionless f32)
AddAssign (Storage f32) (Dimensionless f32)
AddAssign (Storage f32) (&Dimensionless f32)
SubAssign (Storage f32) (Dimensionless f32)
SubAssign (Storage f32) (&Dimensionless f32)
Mul (Quantity f32) ( f32)
Mul (&Quantity f32) ( f32)
Mul (Quantity f32) (& f32)
Mul (&Quantity f32) (& f32)
Mul (Storage f32) (Quantity f32)
Mul (&Storage f32) (Quantity f32)
Mul (Storage f32) (&Quantity f32)
Mul (&Storage f32) (&Quantity f32)
Div (Quantity f32) ( f32)
Div (&Quantity f32) ( f32)
Div (Quantity f32) (& f32)
Div (&Quantity f32) (& f32)
Div (Storage f32) (Quantity f32)
Div (&Storage f32) (Quantity f32)
Div (Storage f32) (&Quantity f32)
Div (&Storage f32) (&Quantity f32)
MulAssign (Quantity f32) ( f32)
MulAssign (Quantity f32) (& f32)
MulAssign (Storage f32) (Dimensionless f32)
MulAssign (Storage f32) (&Dimensionless f32)
DivAssign (Quantity f32) ( f32)
DivAssign (Quantity f32) (& f32)
DivAssign (Storage f32) (Dimensionless f32)
DivAssign (Storage f32) (&Dimensionless f32)
PartialEq (Dimensionless S) ( f32)
PartialEq (Storage f32) (Dimensionless S)
PartialOrd (Dimensionless S) ( f32)
PartialOrd (Storage f32) (Dimensionless S)
Add (Storage f64) (Dimensionless f64)
Add (Storage f64) (&Dimensionless f64)
Add (&Storage f64) (Dimensionless f64)
Add (&Storage f64) (&Dimensionless f64)
Sub (Storage f64) (Dimensionless f64)
Sub (Storage f64) (&Dimensionless f64)
Sub (&Storage f64) (Dimensionless f64)
Sub (&Storage f64) (&Dimensionless f64)
AddAssign (Storage f64) (Dimensionless f64)
AddAssign (Storage f64) (&Dimensionless f64)
SubAssign (Storage f64) (Dimensionless f64)
SubAssign (Storage f64) (&Dimensionless f64)
Mul (Quantity f64) ( f64)
Mul (&Quantity f64) ( f64)
Mul (Quantity f64) (& f64)
Mul (&Quantity f64) (& f64)
Mul (Storage f64) (Quantity f64)
Mul (&Storage f64) (Quantity f64)
Mul (Storage f64) (&Quantity f64)
Mul (&Storage f64) (&Quantity f64)
Div (Quantity f64) ( f64)
Div (&Quantity f64) ( f64)
Div (Quantity f64) (& f64)
Div (&Quantity f64) (& f64)
Div (Storage f64) (Quantity f64)
Div (&Storage f64) (Quantity f64)
Div (Storage f64) (&Quantity f64)
Div (&Storage f64) (&Quantity f64)
MulAssign (Quantity f64) ( f64)
MulAssign (Quantity f64) (& f64)
MulAssign (Storage f64) (Dimensionless f64)
MulAssign (Storage f64) (&Dimensionless f64)
DivAssign (Quantity f64) ( f64)
DivAssign (Quantity f64) (& f64)
DivAssign (Storage f64) (Dimensionless f64)
DivAssign (Storage f64) (&Dimensionless f64)
PartialEq (Dimensionless S) ( f64)
PartialEq (Storage f64) (Dimensionless S)
PartialOrd (Dimensionless S) ( f64)
PartialOrd (Storage f64) (Dimensionless S)