Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add most basic runtime conversion checkers (#208)
To start out with, this is only for `Quantity` (not `QuantityPoint`), and only for same-rep conversions (so no explicit-rep variants). The plan is to start getting some experience with these, check them out on godbolt, make some runtime-checking converters that use them, etc. We can follow up later with a more complete set of APIs. Oh, and docs, too --- this is starting out as an undocumented feature. Every utility's signature looks something like: ```cpp constexpr bool is_foo(Quantity q, TargetUnit target); ``` The instances of `is_foo` that we provide are specifically: - `will_conversion_overflow` - `will_conversion_truncate` - `is_conversion_lossy` The third is the disjunction of the first two. So we would use them something like this: ```cpp constexpr bool ok = is_conversion_lossy(inches(36), feet); ``` The above would return `false`, but would return `true` if we replace `inches(36)` with `inches(37)`. On the implementation side, each magnitude-applying type gets its own dedicated utility. This is nice, because then the function that checks each condition appears directly next to the function that applies the magnitude, so it's easy to check that they're consistent! (For example, when applying a rational magnitude to an integral type, we check whether the _numerator alone_ would cause overflow, because we know we'd be multiplying by that numerator _before_ dividing by the denominator.) Along the way, we also make a new type trait to make it easy to get the appropriate type of magnitude applicator. This made it a lot easier to write the tests. And speaking of tests, we concentrate the vast majority of them in the `detail`-namespaced helpers, which separately check for overflow and truncation. For the `:quantity_test` tests, we just pick one representative test case that is just complicated enough to give us confidence that we're correctly using the utilities. The most exciting test case is the one for `is_conversion_lossy()`. We take one type (`uint8_t`), and check for **every representable value** that a round-trip unit coversion is the identity, _if and only if_ we have identified that conversion as "not lossy". We got 100% correct results for both inches-to-feet (truncation), and feet-to-inches (overflow). Nice!
- Loading branch information