-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
170 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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⁻¹ | ||
``` |