mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-04 12:54:25 +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