added a bit of documentation

This commit is contained in:
Yves Delley
2024-05-12 11:13:00 +02:00
parent c0efdb1790
commit f30fac17f0
4 changed files with 26 additions and 10 deletions

View File

@ -13,6 +13,7 @@
- feat: `fma`, `isfinite`, `isinf`, and `isnan` math function added by [@NAThompson](https://github.com/NAThompson)
- feat: `quantity_point` support added for `quantity_cast` and `value_cast`
- feat: `value_cast<Unit, Representation>` added
- feat: `value_cast<Quantity>(q)`, `value_cast<Quantity>(qp)` and `value_cast<QuantityPoint>(qp)` added by [@burnpanck](https://github.com/burnpanck)
- feat: `interconvertible(QuantitySpec, QuantitySpec)` added
- feat: `qp.quantity_from_zero()` added
- feat: `underlying_type` type trait added

View File

@ -147,3 +147,17 @@ using namespace unit_symbols;
Price price{12.95 * USD};
Scaled spx = value_cast<USD_s, std::int64_t>(price);
```
As a shortcut, instead of providing a unit and a representation type to `value_cast`, you may also provide a
`Quantity` type directly, from which unit and representation type are taken. However, `value_cast<Quantity>`,
still only allows for changes in unit and representation type, but not changing the type of the quantity.
For that, you will have to use a `quantity_cast` instead.
Overloads are also provided for instances of `quantity_point`. Furthermore, in that case, there is
an overload `value_cast<ToQP>(qp)`, which is roughly equivalent to
`value_cast<typename ToQP::quantity_type>(qp).point_for(ToQP::point_origin)`.
In contrast to a separate `value_cast` followed by `point_for` (or vice-versa), the combined
`value_cast` tries to choose the order of the individual conversion steps in such a way,
to avoid both overflow and unnecessary loss of precision. Overflow is a risk because the change of origin point
may require an addition of a potentially large offset (the difference between the origin points),
which may well be outside the range of one or both quantity types.

View File

@ -232,7 +232,8 @@ template<QuantityPoint ToQP, typename QP>
[[nodiscard]] constexpr QuantityPoint auto value_cast(QP&& qp)
{
using qp_type = std::remove_reference_t<QP>;
if constexpr (is_same_v<std::remove_const_t<decltype(ToQP::point_origin)>, std::remove_const_t<decltype(qp_type::point_origin)>>) {
if constexpr (is_same_v<std::remove_const_t<decltype(ToQP::point_origin)>,
std::remove_const_t<decltype(qp_type::point_origin)>>) {
return quantity_point{
value_cast<typename ToQP::quantity_type>(std::forward<QP>(qp).quantity_from(qp_type::point_origin)),
qp_type::point_origin};

View File

@ -1706,15 +1706,15 @@ static_assert(value_cast_is_forbidden<quantity_point<m>, quantity_point<isq::wid
"value_cast shall not cast between different quantity types");
static_assert(value_cast_is_forbidden<quantity_point<isq::width[m]>, quantity_point<m>>(),
"value_cast shall not cast between different quantity types");
static_assert(value_cast<quantity_point<isq::height[m], mean_sea_level>>(quantity_point{2 * isq::height[km], ground_level})
.quantity_from_origin_is_an_implementation_detail_
.numerical_value_in(m) == 2042);
static_assert(value_cast<quantity_point<isq::height[cm], mean_sea_level, int>>(quantity_point{std::int8_t{100} * isq::height[mm], ground_level})
.quantity_from_origin_is_an_implementation_detail_
.numerical_value_in(cm) == 4210);
static_assert(value_cast<quantity_point<isq::height[mm], ground_level, std::int8_t>>(quantity_point{4210 * isq::height[cm], mean_sea_level})
.quantity_from_origin_is_an_implementation_detail_
.numerical_value_in(mm) == 100);
static_assert(value_cast<quantity_point<isq::height[m], mean_sea_level>>(quantity_point{2 * isq::height[km],
ground_level})
.quantity_from_origin_is_an_implementation_detail_.numerical_value_in(m) == 2042);
static_assert(value_cast<quantity_point<isq::height[cm], mean_sea_level, int>>(
quantity_point{std::int8_t{100} * isq::height[mm], ground_level})
.quantity_from_origin_is_an_implementation_detail_.numerical_value_in(cm) == 4210);
static_assert(value_cast<quantity_point<isq::height[mm], ground_level, std::int8_t>>(
quantity_point{4210 * isq::height[cm], mean_sea_level})
.quantity_from_origin_is_an_implementation_detail_.numerical_value_in(mm) == 100);
} // namespace