au icon indicating copy to clipboard operation
au copied to clipboard

Formatting of QuantityPoint

Open vilchanskyio-work opened this issue 1 month ago • 7 comments

Is QuantityPoint formatting supported? It seems not: https://godbolt.org/z/o16MG8hjf . I did not find this mentioned in the documentation.

The godbolt link was taken from https://github.com/aurora-opensource/au/commit/0835a64e43b8fbf3472d953a3bd4a1675f1f471e and changed to use some QuantityPoints.

In case of fmtlib, simply adding

namespace fmt {
template <typename U, typename R>
struct formatter<::au::QuantityPoint<U, R>> : ::au::QuantityFormatter<U, R, ::fmt::formatter> {};
}

in user code did not help.

vilchanskyio-work avatar Oct 30 '25 13:10 vilchanskyio-work

Or, using the expected way to include the library on godbolt: https://godbolt.org/z/3Y1q71Y3b

vilchanskyio-work avatar Oct 30 '25 14:10 vilchanskyio-work

Good catch! The initial version of std::format/fmtlib support was for Quantity only.

QuantityPoint output in general is a little bit of an odd case. As one datapoint, mp-units does not even support output for their "quantity point" concept (at least, last time I checked). On our end, for streaming (<<) output, we had a quirky approach inside of Aurora, where if the Quantity output is Q, then the QuantityPoint output is @(Q), because you are "at" (@) a particular point. I've grown to have mixed feelings about this, and I think it wasn't very well thought through. But, for better or for worse, we did include this in Au when we wrote Au to be an open-sourceable drop-in replacement for our earlier in-house units library.

When we added std::format/fmtlib support, I was reluctant to include QuantityPoint, because of my ambivalence about propagating this convention. But your example makes it clear that this lack of support hurts users. I think it will be straightforward to implement, and we might as well add it for consistency's sake, too. I'll put it in the next release. Thanks!

chiphogg avatar Nov 01 '25 19:11 chiphogg

Thanks for the response. One other approach I tried is converting QuantityPoint into Quantity and then formatting it, but I wasn't able to understand how to convert the former into the latter (as(celsius_qty) didn't compile, if I remember correctly when I was fiddling with it a few days ago, but I may be wrong, but I'm not even sure it makes sense for temperatures to not be a QuantityPoint). If I were able to convert a QuantityPoint into a Quantity (in this case, for the sake of being printable), if that makes sense, then this wouldn't be a problem.

vilchanskyio-work avatar Nov 01 '25 20:11 vilchanskyio-work

A quantity point represents a measurement from an origin. In this case, 0 K. In affine space, you can subtract two points to get a vector (which would be a Quantity). So if you wanted to get the Quantity of degrees Celsius from a QuantityPoint 25 °C from a QuantityPoint of 0 °C, you would use temp - celsius_pt(0). If you wanted to Quantity of degrees Celsius from absolute 0, you would use temp - kelvin_pt(0). Either one of these would result in a Quantity.

hoffbrinkle avatar Nov 01 '25 20:11 hoffbrinkle

I was just typing up the same thing. 😅 Yes, this is the way to go from QuantityPoint to Quantity: subtraction with some other QuantityPoint.

chiphogg avatar Nov 01 '25 20:11 chiphogg

Aha, thanks. I was just revisiting the mile_marker(8) - mile_marker(5) example. For me personally, it's weird that someone would want to have a special type (Quantity) to represent a difference in temperatures instead of an absolute value (QuantityPoint), but even if such type exists, it seems weird to me that it's the difference type that gets first class treatment (for example, in terms of formatting), but I don't work with units extensively (yet :)), perhaps it makes more sense than I currently understand.

vilchanskyio-work avatar Nov 01 '25 20:11 vilchanskyio-work

I agree. When coming into a units library, the distinction is not something we're used to.

Temperature happens to be a great example. If I give you a value and say it's "20 °C" you probably know what I mean. You do the 20 °C - 0 °C in your head and think "about room temperature." However, if the equation is 20 K - 0 K, that value is also "25 °C". But that value represents something completely different than the first value. The first really a point and the second is really a vector (to use affine space terminology).

Coming from the embedded world, I've started to realize that many values we use in every day are actually points. "5 V" is usually "5 volts from ground." There's the 5 miles example (are you "5 miles away", or "at the 5 mile marker"). 11:22 (11 hours, 22 minutes); is that today at 11:22, or just the amount of time that has elapsed?

I took me a while to wrap my head around it, but the ability to distinguish between these cases is definitely useful when trying to develop robust interfaces. 👍

hoffbrinkle avatar Nov 01 '25 21:11 hoffbrinkle