You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Been looking around the docs, source code, and GitHub issues for a bit now, so hopefully I didn't miss anything.
I'm experimenting with creating a simplified ndarray-like type that tracks units. This is similar to option 3 in #237, but I'm using a plain f64 backing array with units being indirectly tracked using PhantomData:
I started off storing quantities directly in the backing array, but switched to f64 so I can guarantee certain operations could be done without an allocation. For example, multiplication can be guaranteed to be done in-place via something like values.iter_mut().for_each(|l| *l *= r), while with a strongly-typed backing array I'd be relying on the optimizer to ensure something like values.into_iter().map(|l| l * r).collect::<Vec<_>>() does not allocate (and from some exploration on Godbolt it seems that that optimization is a bit more iffy for boxed slices than for Vecs, not to mention boxed slices just have worse ergonomics in this case).
(I'm about 50% sure this is safe due to quantities being normalized, but I'm not that confident there aren't edge cases where this assumption is invalid)
This mostly works, but where things get a bit more interesting is trying to get individual quantities back out in a generic context. I know quantities are normalized so for individual instances I can manually use the right unit, but I can't seem to find a way to do this in a generic context. In effect, I have an f64 representing a normalized quantity and I have the quantity type, but I can't put them together to get a strongly typed quantity:
// Ignore missing boundsfnis_valid<Q>(quantity:Q){ ...}impl<Q>Quantities<Q>{fnis_all_valid(&self) -> bool{self.values.iter().map(|f| Q::new(f)).map(|q| is_valid(q)).all()// ^^^^^^^^^ Doesn't exist; need to manually specify base unit}}
A super-duper-yucky-hacky way to deal with this would be to transmute the f64 to the appropriate quantity but that feels rather gross for something that feels like it should be safe. The approach I've been using is a FromF64 trait that I implement on all the quantity types I use, but I feel it's effectively duplicated work for information uom already defines and I feel there's got to be a cleaner way to do what I want.
I also have a somewhat similar issue with getting an f64 out of a Quantity. Is there a way to do so without having to specify the unit - i.e., a way to get the raw f64 corresponding to the base unit in a generic context? As before transmuteing could work as could a (In)toF64 trait, but I feel there's got to be a cleaner way.
Did I miss anything in the docs/code/issues here? Is there a better approach?
The text was updated successfully, but these errors were encountered:
See #231 (comment) and #26 (comment). While these are in the context of const, all fields in the Quantity struct are public and allow you to create an instance without going through the new constructor. Let me know if this works.
Been looking around the docs, source code, and GitHub issues for a bit now, so hopefully I didn't miss anything.
I'm experimenting with creating a simplified ndarray-like type that tracks units. This is similar to option 3 in #237, but I'm using a plain
f64
backing array with units being indirectly tracked usingPhantomData
:I started off storing quantities directly in the backing array, but switched to
f64
so I can guarantee certain operations could be done without an allocation. For example, multiplication can be guaranteed to be done in-place via something likevalues.iter_mut().for_each(|l| *l *= r)
, while with a strongly-typed backing array I'd be relying on the optimizer to ensure something likevalues.into_iter().map(|l| l * r).collect::<Vec<_>>()
does not allocate (and from some exploration on Godbolt it seems that that optimization is a bit more iffy for boxed slices than for Vecs, not to mention boxed slices just have worse ergonomics in this case).(I'm about 50% sure this is safe due to quantities being normalized, but I'm not that confident there aren't edge cases where this assumption is invalid)
This mostly works, but where things get a bit more interesting is trying to get individual quantities back out in a generic context. I know quantities are normalized so for individual instances I can manually use the right unit, but I can't seem to find a way to do this in a generic context. In effect, I have an f64 representing a normalized quantity and I have the quantity type, but I can't put them together to get a strongly typed quantity:
A super-duper-yucky-hacky way to deal with this would be to transmute the
f64
to the appropriate quantity but that feels rather gross for something that feels like it should be safe. The approach I've been using is aFromF64
trait that I implement on all the quantity types I use, but I feel it's effectively duplicated work for informationuom
already defines and I feel there's got to be a cleaner way to do what I want.I also have a somewhat similar issue with getting an
f64
out of aQuantity
. Is there a way to do so without having to specify the unit - i.e., a way to get the rawf64
corresponding to the base unit in a generic context? As beforetransmute
ing could work as could a(In)toF64
trait, but I feel there's got to be a cleaner way.Did I miss anything in the docs/code/issues here? Is there a better approach?
The text was updated successfully, but these errors were encountered: