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
It's a quantity, a dimensionless quantity or the storage type itself
Given by reference or value
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):
Solves #50, so that
compiles fine.
TODO: Fix the impls for glam vecs.
For now, I implemented
Add<&Quantity<S, _>> for Quantity<S, _>
by requiringS: Copy
and wroteQuantity(self.0 + rhs.0)
. Another alternative would have been to requireS: Add<&'S>
, so that the types internal implementation can take care of it and I can simply writeQuantity(self.0 + &rhs.0)
.I went with the first option, because the only non-primitive storage type that is currently supported are
glam
s vectors which areCopy
and do not implementVec3: 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 whetherf32
, ...) 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
andf64
enabled (LHS / RHS / S stand for generic storage types):