99 lines
3.8 KiB
Markdown
99 lines
3.8 KiB
Markdown
---
|
||
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
|
||
the expected `301.15 K`, which will corrupt all further calculations.
|
||
|
||
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.
|
||
|
||
After a lengthy discussion on handling such scenarios, we decided to aid the `quantity` and
|
||
`quantity_point` construction with `absolute<Reference>` and `delta<Reference>` quantity reference
|
||
specifiers. This applies to:
|
||
|
||
- the multiply syntax,
|
||
- 2-parameter `quantity` constructor.
|
||
|
||
Here are the main points of this new design:
|
||
|
||
1. All references/units that do not specify point origin (are not offset units) in their definition
|
||
are considered `delta` by default. This means that `42 * m` creates a `quantity` and is
|
||
the same as calling `42 * delta<m>`.
|
||
2. Multiply syntax is extended to allow `quantity_point` creation with the `42 * absolute<m>`
|
||
syntax. This will provide an implicit zeroth point origin.
|
||
3. For units that specify a point origin (`si::kelvin`, `si::degree_Celsius`, and
|
||
`usc::degree_Fahrenheit`), the user always needs to specify a modifier. This means that:
|
||
- `4 * deg_C` does not compile,
|
||
- `4 * delta<deg_C>` creates a `quantity`.
|
||
- `4 * absolute<deg_C>` creates a `quantity_point`.
|
||
4. The 2-parameter `quantity` constructor requires the same:
|
||
|
||
```cpp
|
||
quantity q1(4, m); // OK
|
||
quantity q2(4, delta<m>); // OK
|
||
quantity q3(4, absolute<m>); // Compile-time error
|
||
quantity q4(4, deg_C); // Compile-time error
|
||
quantity q5(4, delta<deg_C>); // OK
|
||
quantity q6(4, absolute<deg_C>); // Compile-time error
|
||
```
|
||
|
||
The `delta` and `absolute` modifiers are stripped upon construction, so the resulting `quantity`
|
||
and `quantity_point` types use the underlying unit in its type.
|
||
|
||
With such changes, the offending code will not compile, forcing the user to think more about what
|
||
is written. To enable the compilation, the user has to type one of the following:
|
||
|
||
- `quantity_point Temperature(28.0 * delta<deg_C>);`
|
||
- `quantity_point Temperature = 28.0 * absolute<deg_C>;`
|
||
|
||
If the user still insists on using `quantity` instead of a `quantity_point`, the code will
|
||
have to be written in the following way to compile successfully:
|
||
|
||
```cpp
|
||
quantity Temperature = 28.0 * delta<deg_C>;
|
||
```
|
||
|
||
This will yield an invalid result, but now, hopefully, it is clearly readable in the code what is
|
||
wrong here.
|