Support mixed Constant
-Quantity
math functions
#330
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Specifically, we add support for
min
,max
,clamp
, and%
.It turns out that the most economical way to do this is via hidden
friends. The downside is that this change is invasive to
Quantity
,whereas we'd generally rather add functionality from the outside. But
the upsides are that we get to remove a fair bit of extra special casing
that we had done for
Zero
overloads, and even some disambiguatingoverloads. Not only that, but we can now support some combinations that
we hadn't added before, simply because it would have been too much work!
Here's how it works.
The hidden friend approach covers us whenever somebody calls a function
with two exactly-identical types, or whenever one of the types is an
exact match, and the other can implicitly convert to it. This lets
us cover all "shapeshifter types" ---
Zero
,Constant
--- at onestroke. It even automatically covers new shapeshifter types we don't
know about: anything implicitly convertible to
Quantity
will work!The one downside is that using the unqualified forms of
min
,max
,and
clamp
, goes from "recommended" to "mandatory". We found someinstances of this in Aurora's code from testing this PR; they were
easily fixed by changing
au::min(...)
tomin(...)
, etc.For the
min
andmax
implementation, I went with the Walter Brownapproach where
min
prefers to returna
, andmax
prefersb
. Thisis the most general and correct approach w.r.t. how it handles "ties",
although in our specific case this doesn't matter because we're not
returning a reference. Still, I'm glad to put one more example of the
Right Approach out in the wild, and I prefer it to a call to
std::min
because it doesn't force us to take a direct dependency on
<cmath>
.We have two "disambiguating" overloads remaining in
math.hh
, bothapplying to
QuantityPoint
: one formin
, one formax
. I decidednot to add hidden friends there, because the cost of an invasive change,
plus the cost of moving these implementations far from the other
overloads in
math.hh
, outweighs the smaller benefits we would obtainin this case.
Helps #90. At this point, the
Constant
implementation is featurecomplete, and all we need to do is add concrete examples of
Constant
to our library, updating the single-file package script and
documentation!