This lets us remove a ton of special-casing throughout the codebase, and
just generally makes things a lot simpler.
We also remove the ability to take rational powers of `ratio`, including
`sqrt` and `cbrt` helpers, because these are intrinsically ill-defined.
Fixes#369.
For some reason, MSVC seems to want to instantiate these, even though
nobody ever asks for them (as evidenced by the fact that the builds
passed on other architectures).
This commit is huge, but hopefully the cognitive load is not too bad.
The bulk of this commit is just some fairly mechanical updates from
`ratio` to `Magnitude`. Other things to call out:
- `UnitRatio` goes away. We don't need this concept, because Magnitude
can't even _represent_ anything that doesn't satisfy it.
- I commented out some formatting test cases where the precise
expression changes, but the number is completely equivalent. We will
need to decide how we want to handle Magnitude formatting as a
separate, follow-on task. But at least Magnitude gives us all the
tools we'll need to do so!
We provide two new functions, `numerator(m)` and `denominator(m)`, for a
Magnitude `m`. They fulfill the following conditions:
1. `numerator(m)` and `denominator(m)` are always integer Magnitudes.
2. If `m` is rational, then `m == numerator(m) / denominator(m)`.
If `m` is _not_ rational, then the numerator and denominator are not
especially meaningful (there is no uniquely defined "leftover irrational
part"). However, we choose a convention that matches how humans would
write a mixed number. For example, sqrt(27/16) would have a numerator
of 3, denominator of 4, and a "leftover part" of sqrt(3), matching the
"human" way of writing this as [(3 * sqrt(3)) / 4]. This has no use
yet, but it may later be useful in printing the Magnitude of an
anonymous Unit for end users.
To further reduce friction for the upcoming migration, we provide an
implicit conversion from a Magnitude to a `ratio`. We restrict this
operation to rational Magnitudes, and guard this with a `static_assert`.