diff --git a/docs/blog/posts/2.4.0-released.md b/docs/blog/posts/2.4.0-released.md new file mode 100644 index 00000000..4b8f3520 --- /dev/null +++ b/docs/blog/posts/2.4.0-released.md @@ -0,0 +1,210 @@ +--- +draft: true +date: 2024-10-27 +authors: + - mpusz +categories: + - Releases +comments: true +--- + +# mp-units 2.4.0 released! + +**A new product version can be obtained from +[GitHub](https://github.com/mpusz/mp-units/releases/tag/v2.4.0) and +[Conan](https://conan.io/center/recipes/mp-units?version=2.4.0).** + +This release was unexpected. We planned a significant new feature to happen next, but while +preparing for it, and also while writing API Reference documentation, we made so many vital fixes +and improvements that we decided that they deserve a dedicated release first. + +This post describes the most significant improvements, while a much longer list of the changes +introduced by the new version can be found in our [Release Notes](../../release_notes.md#2.4.0). + + + +## ISQ quantities cleanup + +Initially, we kept quantities defined in "IEC 80000-13: Information science and technology" in +a standalone `iec80000` namespace, which was renamed to `iec` in the previous release. +It turned out that this was incorrect. Those quantities are also a part of the ISQ. This is why, +in this release, we moved all of them to the `isq` namespace (:boom: **breaking change** :boom:). + +From now on, `iec` namespace does not provide any quantities and serves purely as a system of units +definition. It contains binary prefixes (based on the powers of two) and some units introduced +by IEC (e.g. `var`, `erlang`, `bit`, or ``baud`). + +!!! note + + The quantities in `iec` namespace are now deprecated and will be removed in future releases. + +Also, it turns out that the latest ISO 80000-3 revision makes a small cleanup to the `phase_speed` +and `group_speed` quantities. Those were always defined as scalar quantities but also had +alternative names `phase_velocity` and `group_velocity`. Those were misleading as _velocity_ is +typically considered a vector quantity. This is why those `XXX_velocity` aliases were +removed (:boom: **breaking change** :boom:). + + +## Units equality + +Previously we assumed that units like `J`, `N m`, and `kg m²/s²` are equal. In some cases, +this might not be entirely correct. Some quantities require a derived unit instead of a unit with +a special name. For example: + +- `N m` should be used for _moment of force_ (instead of `J`), +- `V A` should be used for _apparent power_ (instead of `W`). + +This is why, starting from this release units like `J`, `N m`, and `kg m²/s²` will not compare equal +(:boom: **breaking change** :boom:). However, they are deemed equivalent: + +```cpp +static_assert(equivalent(J, N * m)); +static_assert(equivalent(W, V * A)); +``` + + +## Portable text output + +From the very beginning, the text output of symbols could be formatted in two different ways: + +- Unicode, +- portable using so-called ASCII alternatives. + +**mp-units** used the terms "Unicode" or "ASCII" and 'U' or 'A' formatting options for them. +Even though those terms are widely understood in the C++ community, they are technically +incorrect. + +During the recent SG16 (WG21 Unicode Study Group) meeting, we looked for proper alternatives +and ended up with the "portable" and "UTF-8" terms (:boom: **breaking change** :boom:). + +From now on we will provide the following: + +- `text_encoding::utf8`, `symbol_text::utf8()`, and `U` formatting option, +- `text_encoding::portable`, `symbol_text::portable()`, and `P` formatting option. + +!!! note + + The old identifiers and formatting options are now deprecated and will be removed in future + releases. + + +## `char_traits` removed from `fixed_string` + +During the same SG16 meeting, the room was strongly against providing `char_traits` for +`fixed_string`. This is why `char_traits` support was removed in this release +(:boom: **breaking change** :boom:). + + +## Improved units text output + +In the previous release, we introduced common unit abstraction. Initially, all its components +were printed in parenthesis which contained a list of all the scaled units separated with `=`. +After some feedback, we decided to change it to a new syntax. + +For example, the following: + +```cpp +std::cout << 1 * km + 1 * mi << "\n"; +std::cout << 1 * nmi + 1 * mi << "\n"; +std::cout << 1 * km / h + 1 * m / s << "\n"; +``` + +will print: + +=== "Now" + + ```text + 40771 EQUIV{[1/25146 mi], [1/15625 km]} + 108167 EQUIV{[1/50292 mi], [1/57875 nmi]} + 23 EQUIV{[1/5 km/h], [1/18 m/s]} + ``` + +=== "Before" + + ```text + 40771 ([1/25146] mi = [1/15625] km) + 108167 ([1/50292] mi = [1/57875] nmi) + 23 ([1/5] km/h = [1/18] m/s) + ``` + +As we can see above, the scaled units output changed as well. Now, the entire scaled unit is +encapsulated within `[...]` brackets to better denote its scope. + +Additionally, small magnitudes of scaled units do not use the power of `10`, and also scaled +units do not have a composition priority over the derived units anymore. + +As a result of those changes, the following: + +```cpp +constexpr Unit auto L_per_100km = L / (mag<100> * km); +std::cout << 6.7 * L_per_100km << "\n"; +``` + +prints: + +=== "Now" + + ```text + 6.7 L/[100 km] + ``` + +=== "Before" + + ```text + 6.7 × 10⁻² l/km + ``` + +One more change that we can see above is that litres now use "L" instead of "l" for the symbol. +The latter one too often is confused with the number `1`. + +The next improvement adds proper formatting support for magnitudes. All of the formatting options +that were working before for the unit symbols now also work for magnitudes. + +For example: + +```cpp +using enum text_encoding; +using enum unit_symbol_solidus; +using usf = unit_symbol_formatting; + +static_assert(unit_symbol(mag<1> / (mag<2> * mag)*metre) == "[2⁻¹ 𝜋⁻¹ m]"); +static_assert(unit_symbol(mag<1> / (mag<2> * mag)*metre) == "[1/(2 𝜋) m]"); +static_assert(unit_symbol(mag<1> / (mag<2> * mag)*metre) == + "[1/(2 pi) m]"); +``` + +As we can see above, the library also learned how to print magnitude symbols. This required +a change in the `mag_constant` definition. Now, it takes a magnitude symbol and has to be `final` +like for other similar types in the library (:boom: **breaking change** :boom:): + +```cpp +inline constexpr struct pi final : mag_constant> {} pi; +inline constexpr auto π = pi; +``` + +## Unicode identifiers + +The example above introduced something interesting: a `π` identifier for a variable. With the +latest changes to the C++ language, we can officially use Unicode symbols as identifiers in +the C++ code. + +In this release, we've added support for those not only for `π` but also for unit symbols. +Now we can type the following: + +=== "With UTF-8 glyphs" + + ```cpp + quantity resistance = 60 * kΩ; + quantity capacitance = 100 * µF; + ``` + +=== "Portable" + + ```cpp + quantity resistance = 60 * kohm; + quantity capacitance = 100 * uF; + ``` + +This might make the source code easier to understand, but typing those identifiers can be tricky. +Sometimes, the best solution to type it might be a copy-paste approach. If we do not like this +idea, we can still use old portable identifiers for those as well.