Skip to content

Commit

Permalink
docs: 2.1.0 release announcement
Browse files Browse the repository at this point in the history
  • Loading branch information
mpusz committed Jan 3, 2024
1 parent d5668b7 commit af075be
Showing 1 changed file with 170 additions and 0 deletions.
170 changes: 170 additions & 0 deletions docs/blog/posts/2.1.0-released.md
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⁻¹
```

0 comments on commit af075be

Please sign in to comment.