mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-04 20:54:28 +02:00
docs: 2.1.0 release announcement
This commit is contained in:
170
docs/blog/posts/2.1.0-released.md
Normal file
170
docs/blog/posts/2.1.0-released.md
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
---
|
||||||
|
date: 2023-12-09
|
||||||
|
authors:
|
||||||
|
- mpusz
|
||||||
|
categories:
|
||||||
|
- Releases
|
||||||
|
---
|
||||||
|
|
||||||
|
# mp-units 2.1.0 released!
|
||||||
|
|
||||||
|
**A new product version can be obtained from
|
||||||
|
[GitHub](https://github.com/mpusz/mp-units/releases/tag/v2.1.0) and
|
||||||
|
[Conan](https://conan.io/center/recipes/mp-units?version=2.1.0).**
|
||||||
|
|
||||||
|
The list of the most significant changes introduced by the new version can be found in our
|
||||||
|
[Release Notes](../../release_notes.md#2.1.0). We will also describe the most important of them
|
||||||
|
in this post.
|
||||||
|
|
||||||
|
<!-- more -->
|
||||||
|
|
||||||
|
## No more parenthesis while creating quantities with derived units
|
||||||
|
|
||||||
|
The V2 design introduced a way to create a `quantity` by multiplying a raw value and a unit:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
quantity q1 = 42 * m;
|
||||||
|
```
|
||||||
|
|
||||||
|
However, this meant that when we wanted to create a quantity having a derived unit, we had to put
|
||||||
|
parenthesis around the unit equation or create a custom value of the named unit:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
quantity q2 = 60 * (km / h);
|
||||||
|
|
||||||
|
constexpr auto kmph = km / h;
|
||||||
|
quantity q3 = 60 * kmph;
|
||||||
|
|
||||||
|
quantity q4 = 50 * (1 / s);
|
||||||
|
```
|
||||||
|
|
||||||
|
With the new version, we removed this restriction, and now we can type:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
quantity q5 = 60 * km / h;
|
||||||
|
quantity q6 = 50 / s;
|
||||||
|
```
|
||||||
|
|
||||||
|
As a side effect, we introduced a **breaking change**. We can't use the following definition of
|
||||||
|
hertz anymore:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
inline constexpr struct hertz : named_unit<"Hz", 1 / second, kind_of<isq::frequency>> {} hertz;
|
||||||
|
```
|
||||||
|
|
||||||
|
and have to type either:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
inline constexpr struct hertz : named_unit<"Hz", one / second, kind_of<isq::frequency>> {} hertz;
|
||||||
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
inline constexpr struct hertz : named_unit<"Hz", inverse(second), kind_of<isq::frequency>> {} hertz;
|
||||||
|
```
|
||||||
|
|
||||||
|
To be consistent, we applied the same change to the dimensions and quantity
|
||||||
|
specifications definitions. Now, to define a _frequency_ we have to type:
|
||||||
|
|
||||||
|
=== "C++23"
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
inline constexpr struct frequency : quantity_spec<inverse(period_duration)> {} frequency;
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "C++20"
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
inline constexpr struct frequency : quantity_spec<frequency, inverse(period_duration)> {} frequency;
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Portable"
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
QUANTITY_SPEC(frequency, inverse(period_duration));
|
||||||
|
```
|
||||||
|
|
||||||
|
## `make_xxx` factory functions replaced with two-parameter constructors
|
||||||
|
|
||||||
|
In the initial version of the V2 framework, if someone did not like the multiply syntax to create
|
||||||
|
a `quantity` we provided the `make_quantity()` factory function. A similar approach was used for
|
||||||
|
`quantity_point` creation.
|
||||||
|
|
||||||
|
This version removes those (**breaking change**) and introduces two parameter constructors:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
quantity q(42, si::metre);
|
||||||
|
quantity_point qp(q, mean_sea_level);
|
||||||
|
```
|
||||||
|
|
||||||
|
The above change encourages a better design and results in a terser code.
|
||||||
|
|
||||||
|
## Improved definitions of becquerel, gray, and sievert
|
||||||
|
|
||||||
|
In the initial V2 version, we lacked the definitions of the atomic and nuclear physics quantities,
|
||||||
|
which resulted in simplified and unsafe definitions of becquerel, gray, and sievert units. We still
|
||||||
|
do not model most of the quantities from this domain, but we've added the ones that are necessary
|
||||||
|
for the definition of those units.
|
||||||
|
|
||||||
|
Thanks to the above, the following expressions will not compile:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
quantity q1 = 1 * Hz + 1 * Bq;
|
||||||
|
quantity<si::sievert> q2 = 42 * Gy;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Compatibility with other libraries redesigned
|
||||||
|
|
||||||
|
Another significant improvement in this version was redesigning the way we provide compatibility
|
||||||
|
with other similar libraries. The interfaces of `quantity_like_traits` and `quantity_point_like_traits`
|
||||||
|
were changed and extended to provide conversion not only from but also to entities from other
|
||||||
|
libraries (**breaking change**).
|
||||||
|
|
||||||
|
We've also introduced an innovative approach that allows us to specify if such conversions should
|
||||||
|
happen implicitly or if they need to be forced explicitly.
|
||||||
|
|
||||||
|
More on this subject can be found in the
|
||||||
|
[Interoperability with Other Libraries](../../users_guide/use_cases/interoperability_with_other_libraries.md)
|
||||||
|
chapter.
|
||||||
|
|
||||||
|
|
||||||
|
## Point origins can now be derived from each other
|
||||||
|
|
||||||
|
Previously, each class derived from `absolute_point_origin` was considered a unique independent
|
||||||
|
point origin. On the other hand, it was OK to derive multiple classes from the same
|
||||||
|
`relative_point_origin`, and those were specifying the same point in the domain. We found this
|
||||||
|
confusing and limiting. This is why, in this version, the `absolute_point_origin` uses a CRTP idiom
|
||||||
|
to be able to detect between points that should be considered different from the ones that should
|
||||||
|
be equivalent.
|
||||||
|
|
||||||
|
*[CRTP]: Curiously Recurring Template Pattern
|
||||||
|
|
||||||
|
If we derive from the same instantiation of `absolute_point_origin` we end up with an equivalent
|
||||||
|
point origin. This change allows us to provide different names for the same temperature points:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
inline constexpr struct absolute_zero : absolute_point_origin<absolute_zero, isq::thermodynamic_temperature> {} absolute_zero;
|
||||||
|
inline constexpr struct zeroth_kelvin : decltype(absolute_zero) {} zeroth_kelvin;
|
||||||
|
|
||||||
|
inline constexpr struct ice_point : relative_point_origin<absolute_zero + 273.15 * kelvin> {} ice_point;
|
||||||
|
inline constexpr struct zeroth_degree_Celsius : decltype(ice_point) {} zeroth_degree_Celsius;
|
||||||
|
```
|
||||||
|
|
||||||
|
Please note that this is a **breaking change** as well.
|
||||||
|
|
||||||
|
|
||||||
|
## Unit symbol text can now be properly used at runtime
|
||||||
|
|
||||||
|
The interface of the previous definition of `unit_symbol` function allowed the use of the returned
|
||||||
|
buffer only at compile-time. This was too limiting as users often want to use unit symbols at
|
||||||
|
runtime (e.g., print them to the console). The new version redesigned the interface of this
|
||||||
|
function (**breaking change**) to return a buffer that can be properly used at both compilation and
|
||||||
|
runtime:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
std::string_view unit1 = unit_symbol(m / s);
|
||||||
|
std::cout << unit1 << "\n"; // m/s
|
||||||
|
std::string_view unit2 = unit_symbol<{.solidus = unit_symbol_solidus::never}>(m / s);
|
||||||
|
std::cout << unit2 << "\n"; // m s⁻¹
|
||||||
|
```
|
Reference in New Issue
Block a user