2024-06-21 08:21:35 +02:00
|
|
|
|
---
|
|
|
|
|
|
draft: true
|
|
|
|
|
|
date: 2024-06-15
|
|
|
|
|
|
authors:
|
|
|
|
|
|
- mpusz
|
|
|
|
|
|
categories:
|
|
|
|
|
|
- Releases
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# mp-units 2.3.0 released!
|
|
|
|
|
|
|
|
|
|
|
|
**A new product version can be obtained from
|
|
|
|
|
|
[GitHub](https://github.com/mpusz/mp-units/releases/tag/v2.3.0) and
|
|
|
|
|
|
[Conan](https://conan.io/center/recipes/mp-units?version=2.3.0).**
|
|
|
|
|
|
|
|
|
|
|
|
This release fine-tunes many key features of the library. This post describes those and a few
|
|
|
|
|
|
other smaller interesting improvements, while a much longer list of the most significant changes
|
|
|
|
|
|
introduced by the new version can be found in our [Release Notes](../../release_notes.md#2.3.0).
|
|
|
|
|
|
|
|
|
|
|
|
<!-- more -->
|
|
|
|
|
|
|
|
|
|
|
|
## Quantity reference specifiers
|
|
|
|
|
|
|
|
|
|
|
|
The features described in this chapter directly solve an issue raised on
|
|
|
|
|
|
[std-proposals reflector](https://lists.isocpp.org/std-proposals/2024/06/10118.php). As it was
|
|
|
|
|
|
reported, the code below may look correct, but it provides an invalid result:
|
|
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
|
quantity Volume = 1.0 * m3;
|
|
|
|
|
|
quantity Temperature = 28.0 * deg_C;
|
|
|
|
|
|
quantity n_ = 0.04401 * kg / mol;
|
|
|
|
|
|
quantity R_boltzman = 8.314 * N * m / (K * mol);
|
|
|
|
|
|
quantity mass = 40.0 * kg;
|
|
|
|
|
|
quantity Pressure = R_boltzman * Temperature.in(K) * mass / n_ / Volume;
|
|
|
|
|
|
std::cout << Pressure << "\n";
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
The problem is related to the accidental usage of a `quantity` rather than `quantity_point` for
|
|
|
|
|
|
`Temperature`. This means that after conversion to kelvins, we will get `28 K` instead of
|
2024-06-30 12:03:24 +02:00
|
|
|
|
the expected `301.15 K`, corrupting all further calculations.
|
2024-06-21 08:21:35 +02:00
|
|
|
|
|
|
|
|
|
|
A correct code should use a `quantity_point`:
|
|
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
|
quantity_point Temperature(28.0 * deg_C);
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
This might be an obvious thing for domain experts, but new users of the library may not be aware
|
|
|
|
|
|
of the affine space abstractions and how they influence temperature handling.
|
|
|
|
|
|
|
2024-06-30 12:03:24 +02:00
|
|
|
|
After a lengthy discussion on handling such scenarios, we decided to:
|
2024-06-21 08:21:35 +02:00
|
|
|
|
|
2024-06-30 12:03:24 +02:00
|
|
|
|
- make the above code ill-formed,
|
|
|
|
|
|
- provide an alternative way to create a `quantity` with the `delta` quantity construction helper.
|
2024-06-21 08:21:35 +02:00
|
|
|
|
|
|
|
|
|
|
Here are the main points of this new design:
|
|
|
|
|
|
|
2024-06-30 12:03:24 +02:00
|
|
|
|
1. All references/units that specify point origin in their definition (i.e., `si::kelvin`,
|
|
|
|
|
|
`si::degree_Celsius`, and `usc::degree_Fahrenheit`) are excluded from the multiply syntax
|
|
|
|
|
|
(:boom: **breaking change** :boom:).
|
|
|
|
|
|
2. A new `delta` quantity construction helper is introduced:
|
2024-06-21 08:21:35 +02:00
|
|
|
|
|
2024-06-30 12:03:24 +02:00
|
|
|
|
- `delta<m>(42)` results with a `quantity<si::metre, int>`,
|
|
|
|
|
|
- `delta<deg_C>(5)` results with a `quantity<si::deg_C, int>`.
|
2024-06-21 08:21:35 +02:00
|
|
|
|
|
2024-06-30 12:03:24 +02:00
|
|
|
|
3. A new `absolute` quantity point construction helper is introduced:
|
2024-06-21 08:21:35 +02:00
|
|
|
|
|
2024-06-30 12:03:24 +02:00
|
|
|
|
- `absolute<m>(42)` results with a `quantity_point<si::metre, zeroth_point_origin<kind_of<isq::length>>{}, int>`,
|
|
|
|
|
|
- `absolute<deg_C>(5)` results with a `quantity<si::metre, si::ice_point, int>`.
|
2024-06-21 08:21:35 +02:00
|
|
|
|
|
2024-06-30 12:03:24 +02:00
|
|
|
|
!!! info
|
2024-06-21 08:21:35 +02:00
|
|
|
|
|
2024-06-30 12:03:24 +02:00
|
|
|
|
Please note that `si::kelvin` is also excluded from the multiply syntax to prevent the
|
|
|
|
|
|
following surprising issues:
|
2024-06-21 08:21:35 +02:00
|
|
|
|
|
2024-06-30 12:03:24 +02:00
|
|
|
|
=== "Now"
|
2024-06-21 08:21:35 +02:00
|
|
|
|
|
2024-06-30 12:03:24 +02:00
|
|
|
|
```cpp
|
|
|
|
|
|
quantity q = delta<K>(300);
|
|
|
|
|
|
quantity_point qp = absolute<K>(300);
|
|
|
|
|
|
static_assert(q.in(deg_C) != qp.in(deg_C).quantity_from_zero());
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
=== "Before"
|
|
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
|
quantity q(300 * K);
|
|
|
|
|
|
quantity_point qp(300 * K);
|
|
|
|
|
|
static_assert(q.in(deg_C) != qp.in(deg_C).quantity_from_zero());
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
We believe that the code enforced with new utilities makes it much easier to understand what
|
|
|
|
|
|
happens here.
|
|
|
|
|
|
|
|
|
|
|
|
With such changes to the interface design, the offending code will not compile as initially written.
|
|
|
|
|
|
Users will be forced to think more about what they write. To enable the compilation, the users have
|
|
|
|
|
|
to explicitly create a:
|
|
|
|
|
|
|
|
|
|
|
|
- `quantity_point` (the intended abstraction in this example) with any of the below syntaxes:
|
|
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
|
quantity_point Temperature = absolute<deg_C>(28.0);
|
|
|
|
|
|
auto Temperature = absolute<deg_C>(28.0);
|
|
|
|
|
|
quantity_point Temperature(delta<deg_C>(28.0));
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
- `quantity` (an incorrect abstraction in this example) with:
|
|
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
|
quantity Temperature = delta<deg_C>(28.0);
|
|
|
|
|
|
auto Temperature = delta<deg_C>(28.0);
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Thanks to the new design, we can immediately see what happens here and why the result might be
|
|
|
|
|
|
incorrect in the second case.
|