Files
mp-units/docs/blog/posts/2.3.0-released.md
T

116 lines
4.0 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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`, corrupting 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:
- make the above code ill-formed,
- provide an alternative way to create a `quantity` with the `delta` quantity construction helper.
Here are the main points of this new design:
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:
- `delta<m>(42)` results with a `quantity<si::metre, int>`,
- `delta<deg_C>(5)` results with a `quantity<si::deg_C, int>`.
3. A new `absolute` quantity point construction helper is introduced:
- `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>`.
!!! info
Please note that `si::kelvin` is also excluded from the multiply syntax to prevent the
following surprising issues:
=== "Now"
```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.