aurora-opensource / au

A C++14-compatible physical units library with no dependencies and a single-file delivery option. Emphasis on safety, accessibility, performance, and developer experience.
Apache License 2.0
329 stars 21 forks source link

Gather factors and add labels for scaled units #332

Open chiphogg opened 1 day ago

chiphogg commented 1 day ago

First, when multiplying a ScaledUnit by another magnitude, we now fold it into the existing magnitude of the scaled unit. Previously, we'd end up with ScaledUnit<ScaledUnit<U, M1>, M2>, and so on. We also now omit any "trivial" scaling factors, whether because we're scaling by mag<1>(), or (more commonly) whether we've applied a bunch of different scale factors and they all cancel out.

(We did need to tweak a few cases that were relying on U{} * mag<1>() being meaningfully different from U{}.)

Next, we now auto-generate labels for ScaledUnit specializations. For ScaledUnit<U, M>, if U has label "U", and M has label "M", we generate a label "[M U]" --- or, if "M" contains an exposed slash "/", we'll generate the label "[(M) U]" for lack of ambiguity. This resolves the vast majority of [UNLABELED_UNIT] labels. The remaining work on #85 is simply to generate labels for a wider variety of magnitude label categories.

Finally: we formerly had no way to decide ordering between units that are both specializations of ScaledUnit, which do have identical dimension and magnitude, and yet are not the same unit. (For example, something like "[(1 / 4) ft]" and "[3 in]".) This may have been somewhat obscure in the past, but with the upcoming work on #105, it's about to become very common. We added a test case that exposes this, and then updated our ordering code to handle this case.

Helps #85. Unblocks #105.