mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-05 13:14:29 +02:00
Merge branch 'master' into add_fma
This commit is contained in:
4
.github/workflows/documentation.yml
vendored
4
.github/workflows/documentation.yml
vendored
@@ -34,6 +34,8 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
- uses: actions/setup-python@v4
|
- uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
@@ -46,7 +48,7 @@ jobs:
|
|||||||
mkdocs-material-
|
mkdocs-material-
|
||||||
- name: Installing pip packages
|
- name: Installing pip packages
|
||||||
run: |
|
run: |
|
||||||
pip install conan mkdocs-material mike
|
pip install conan mkdocs-material mkdocs-rss-plugin mike
|
||||||
- name: Prepare git
|
- name: Prepare git
|
||||||
run: |
|
run: |
|
||||||
git config --global user.name github-actions
|
git config --global user.name github-actions
|
||||||
|
6
docs/blog/.authors.yml
Normal file
6
docs/blog/.authors.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
authors:
|
||||||
|
mpusz:
|
||||||
|
name: Mateusz Pusz
|
||||||
|
description: Creator
|
||||||
|
avatar: https://avatars.githubusercontent.com/u/506260
|
||||||
|
url: https://github.com/mpusz
|
1
docs/blog/index.md
Normal file
1
docs/blog/index.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
# Blog
|
130
docs/blog/posts/2.0.0-released.md
Normal file
130
docs/blog/posts/2.0.0-released.md
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
---
|
||||||
|
date: 2023-09-24
|
||||||
|
authors:
|
||||||
|
- mpusz
|
||||||
|
categories:
|
||||||
|
- Releases
|
||||||
|
---
|
||||||
|
|
||||||
|
# What's new in mp-units 2.0?
|
||||||
|
|
||||||
|
**After a year of hard work, we've just released mp-units 2.0.0. It can be obtained from
|
||||||
|
[GitHub](https://github.com/mpusz/mp-units/releases/tag/v2.0.0) and
|
||||||
|
[Conan](https://conan.io/center/recipes/mp-units?version=2.0.0).**
|
||||||
|
|
||||||
|
In this post, we will describe all the changes introduced by the new version.
|
||||||
|
|
||||||
|
<!-- more -->
|
||||||
|
|
||||||
|
## Why 2.0 if 1.0 was never released?
|
||||||
|
|
||||||
|
Version 2 of the **mp-units** project is a huge change and a new quality for the users.
|
||||||
|
We did not want to pretend that 2.0 is an evolutionary upgrade of the previous version of the
|
||||||
|
project. It feels like a different product.
|
||||||
|
|
||||||
|
We could start a new repo named "mp-units-v2" similarly to [range-v3](https://github.com/ericniebler/range-v3)
|
||||||
|
but we decided not to go this path. We kept the same repo and made the scope of the changes and
|
||||||
|
potential breakage explicit with a drastic bump in the project version.
|
||||||
|
|
||||||
|
## What has changed?
|
||||||
|
|
||||||
|
The answer is "nearly everything". The whole library and its documentation were rewritten nearly
|
||||||
|
from scratch.
|
||||||
|
|
||||||
|
Here are the significant changes that the users can observe:
|
||||||
|
|
||||||
|
- **Repository name**
|
||||||
|
|
||||||
|
If you didn't notice, the repository name was changed from "mpusz/units" to "mpusz/mp-units".
|
||||||
|
|
||||||
|
- **Header files content and layout**
|
||||||
|
|
||||||
|
Previously, all the header files resided in the _include/units_ directory, and now they can be
|
||||||
|
found in _include/mp-units_. The project file tree was significantly changed as well. Many
|
||||||
|
files were moved to different subdirectories or renamed.
|
||||||
|
|
||||||
|
- **Namespace**
|
||||||
|
|
||||||
|
Previously, all the definitions were provided in the `units` namespace, and now they are in the
|
||||||
|
`mp_units` one.
|
||||||
|
|
||||||
|
- **Abstractions, interfaces, definitions**
|
||||||
|
|
||||||
|
The interfaces of all of the types were refactored, and we have a new way to construct a `quantity`
|
||||||
|
and `quantity_point`, we got unit symbols, and nearly all of the template arguments are now passed
|
||||||
|
by values thanks to class NTTP extensions in C++20. Also, systems definitions are much terser now
|
||||||
|
thanks to a new design approach.
|
||||||
|
|
||||||
|
*[NTTP]: Non-Type Template Parameter
|
||||||
|
|
||||||
|
- **Conan 2.0**
|
||||||
|
|
||||||
|
Also, now we support Conan 2.0, which provides an updated way of handling dependencies.
|
||||||
|
|
||||||
|
## What is gone?
|
||||||
|
|
||||||
|
Some cornerstones of the initial design did not prove in practice and were removed while
|
||||||
|
we moved to version 2.
|
||||||
|
|
||||||
|
### The downcasting facility
|
||||||
|
|
||||||
|
The first and the most important of such features was removing the downcasting facility.
|
||||||
|
This feature is still a powerful metaprogramming technique that allows users to map long class template
|
||||||
|
instantiations to nicely named, short, and easy-to-understand user's strong types.
|
||||||
|
|
||||||
|
Such mapping works perfectly fine for 1-to-1 relationships. However, we often deal with N-to-1 connections in the quantities and units domain. Here are only a few such examples:
|
||||||
|
|
||||||
|
- _work_ and _torque_ have the same dimension $L^2MT^{-2}$,
|
||||||
|
- becquerel and hertz have the same definition of $s^{-1}$,
|
||||||
|
- litre and cubic decimetre have the same factor.
|
||||||
|
|
||||||
|
In the above examples, multiple entities "wanted" to register different names for identical class
|
||||||
|
template instantiations, resulting in compile-time errors. We had to invent some hacks and
|
||||||
|
workarounds to make it work, but we were never satisfied with the outcome.
|
||||||
|
|
||||||
|
Additionally, this facility could easily lead to ODR violations or provide different results
|
||||||
|
depending on which header files were included in the translation units. This was too vulnerable
|
||||||
|
to be considered a good practice here.
|
||||||
|
|
||||||
|
*[ODR]: One Definition Rule
|
||||||
|
|
||||||
|
### No UDLs anymore
|
||||||
|
|
||||||
|
Over the years, we have learned that UDLs are not a good solution either. More information on this
|
||||||
|
subject can be found in the
|
||||||
|
[Why don't we use UDLs to create quantities?](../../getting_started/faq.md#why-dont-we-use-udls-to-create-quantities)
|
||||||
|
chapter.
|
||||||
|
|
||||||
|
*[UDL]: User-Defined Literals
|
||||||
|
|
||||||
|
|
||||||
|
## New look and feel
|
||||||
|
|
||||||
|
Here is a concise example showing you the new look and feel of the library:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include <mp-units/format.h>
|
||||||
|
#include <mp-units/systems/isq/isq.h>
|
||||||
|
#include <mp-units/systems/si/si.h>
|
||||||
|
#include <format>
|
||||||
|
|
||||||
|
using namespace mp_units;
|
||||||
|
using namespace mp_units::si::unit_symbols;
|
||||||
|
|
||||||
|
quantity<isq::speed[m / s]> avg_speed(quantity<si::metre> d,
|
||||||
|
quantity<si::second> t)
|
||||||
|
{ return d / t; }
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
auto speed = avg_speed(220 * km, 2 * h);
|
||||||
|
std::println("{}", speed); // 30.5556 m/s
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
All of the changes we provided, although breaking ones, resulted in much better,
|
||||||
|
easier, and safer abstractions. These offer a new quantity on the market and hopefully will be
|
||||||
|
appreciated by our users.
|
||||||
|
|
||||||
|
Please check our new documentation to learn about the latest version of the project and find out
|
||||||
|
how to benefit from all the new cool stuff we have here.
|
50
docs/blog/posts/kona-2023-report.md
Normal file
50
docs/blog/posts/kona-2023-report.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
---
|
||||||
|
date: 2023-11-12
|
||||||
|
authors:
|
||||||
|
- mpusz
|
||||||
|
categories:
|
||||||
|
- WG21
|
||||||
|
---
|
||||||
|
|
||||||
|
# Report from the Kona 2023 ISO C++ Committee meeting
|
||||||
|
|
||||||
|
**Several groups in the ISO C++ Committee reviewed the [P1935: A C++ Approach to Physical Units](https://wg21.link/p1935)
|
||||||
|
proposal in Belfast 2019 and Prague 2020. All those groups expressed interest in the potential
|
||||||
|
standardization of such a library and encouraged further work. The authors also got valuable
|
||||||
|
initial feedback that highly influenced the design of the V2 version of the mp-units library.**
|
||||||
|
|
||||||
|
In the following years, we scoped on getting more feedback from the production and design and
|
||||||
|
developed version 2 of the **mp-units** library that resolves many issues raised by the users and
|
||||||
|
Committee members. The features and interfaces of this version are close to being the best we can
|
||||||
|
get with the current version of the C++ language standard.
|
||||||
|
|
||||||
|
<!-- more -->
|
||||||
|
|
||||||
|
For the last ISO C++ Committee meeting, we provided three new proposals related to the
|
||||||
|
standardization of the quantities and units library:
|
||||||
|
|
||||||
|
- [P2980: A motivation, scope, and plan for a physical quantities and units library](https://wg21.link/p2980R1),
|
||||||
|
- [P2981: Improving our safety with a physical quantities and units library](https://wg21.link/p2981R1),
|
||||||
|
- [P2982: `std::quantity` as a numeric type](https://wg21.link/p2982R1).
|
||||||
|
|
||||||
|
Those were reviewed and briefly discussed in several groups: Numerics (SG6), Safety & Security
|
||||||
|
(SG23), and Library Evolution Working Group (LEWG). Most of the feedback was positive, and
|
||||||
|
the Committee is interested in spending more time on such proposals.
|
||||||
|
|
||||||
|
!!! question "LEWG POLL: Given that our time is limited, more time should be promised for a quantities and units library"
|
||||||
|
|
||||||
|
| SF | F | N | A | SA |
|
||||||
|
|----|----|---|---|----|
|
||||||
|
| 10 | 13 | 4 | 0 | 0 |
|
||||||
|
|
||||||
|
Attendance: 22 + 6
|
||||||
|
|
||||||
|
Number of Authors: 4
|
||||||
|
|
||||||
|
Authors’ position: 4x SF
|
||||||
|
|
||||||
|
Outcome: Strong consensus in favor
|
||||||
|
|
||||||
|
Additionally, some concerns were raised about the large scope of the proposal. We were encouraged
|
||||||
|
to come back with more details and design rationale in a unified paper. This is what we are working
|
||||||
|
on now for the next Committee meeting that will happen in mid-March 2024 in Tokyo.
|
10
mkdocs.yml
10
mkdocs.yml
@@ -51,6 +51,14 @@ theme:
|
|||||||
|
|
||||||
# Plugins
|
# Plugins
|
||||||
plugins:
|
plugins:
|
||||||
|
- blog
|
||||||
|
- rss:
|
||||||
|
match_path: blog/posts/.*
|
||||||
|
date_from_meta:
|
||||||
|
as_creation: date
|
||||||
|
categories:
|
||||||
|
- categories
|
||||||
|
- tags
|
||||||
- search
|
- search
|
||||||
- tags:
|
- tags:
|
||||||
tags_file: users_guide/examples/tags_index.md
|
tags_file: users_guide/examples/tags_index.md
|
||||||
@@ -108,6 +116,8 @@ nav:
|
|||||||
- Quick Start: getting_started/quick_start.md
|
- Quick Start: getting_started/quick_start.md
|
||||||
- Installation and Usage: getting_started/installation_and_usage.md
|
- Installation and Usage: getting_started/installation_and_usage.md
|
||||||
- FAQ: getting_started/faq.md
|
- FAQ: getting_started/faq.md
|
||||||
|
- Blog:
|
||||||
|
- blog/index.md
|
||||||
- User's Guide:
|
- User's Guide:
|
||||||
- Terms and Definitions: users_guide/terms_and_definitions.md
|
- Terms and Definitions: users_guide/terms_and_definitions.md
|
||||||
- Framework Basics:
|
- Framework Basics:
|
||||||
|
@@ -2,4 +2,5 @@ conan
|
|||||||
pre-commit
|
pre-commit
|
||||||
identify
|
identify
|
||||||
mkdocs-material
|
mkdocs-material
|
||||||
|
mkdocs-rss-plugin
|
||||||
mike
|
mike
|
||||||
|
@@ -144,18 +144,12 @@ template<auto R, typename Rep>
|
|||||||
* @param b: Addend
|
* @param b: Addend
|
||||||
* @return Quantity: The nearest floating point representable to ax+b
|
* @return Quantity: The nearest floating point representable to ax+b
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<auto R, auto S, auto T, typename Rep1, typename Rep2, typename Rep3>
|
template<auto R, auto S, auto T, typename Rep1, typename Rep2, typename Rep3>
|
||||||
[[nodiscard]] constexpr QuantityOf<common_quantity_spec(get_quantity_spec(R) * get_quantity_spec(S),
|
[[nodiscard]] constexpr QuantityOf<common_quantity_spec(get_quantity_spec(R) * get_quantity_spec(S),
|
||||||
get_quantity_spec(T))> auto
|
get_quantity_spec(T))> auto
|
||||||
fma( // QuantityOf takes a QuantitySpec as an argument
|
fma(const quantity<R, Rep1>& a, const quantity<S, Rep2>& x, const quantity<T, Rep3>& b) noexcept
|
||||||
const quantity<R, Rep1>& a, const quantity<S, Rep2>& x, const quantity<T, Rep3>& b) noexcept
|
requires requires { common_quantity_spec(get_quantity_spec(R) * get_quantity_spec(S), get_quantity_spec(T)); } &&
|
||||||
requires requires {
|
(get_unit(R) * get_unit(S) == get_unit(T)) &&
|
||||||
common_quantity_spec(get_quantity_spec(R) * get_quantity_spec(S), get_quantity_spec(T));
|
|
||||||
} && // or just common_reference but I wanted to express that the quantity types must match here and we don't care
|
|
||||||
// too much about units
|
|
||||||
(get_unit(R) * get_unit(S) ==
|
|
||||||
get_unit(T)) && // units that we want to add are equivalent (have the same magnitude)
|
|
||||||
(
|
(
|
||||||
requires {
|
requires {
|
||||||
fma(a.numerical_value_ref_in(a.unit), x.numerical_value_ref_in(x.unit),
|
fma(a.numerical_value_ref_in(a.unit), x.numerical_value_ref_in(x.unit),
|
||||||
@@ -168,7 +162,8 @@ fma( // QuantityOf takes a QuantitySpec as an argument
|
|||||||
{
|
{
|
||||||
using std::fma;
|
using std::fma;
|
||||||
return quantity{
|
return quantity{
|
||||||
fma(a.numerical_value_ref_in(a.unit), x.numerical_value_ref_in(x.unit), b.numerical_value_ref_in(b.unit)), T};
|
fma(a.numerical_value_ref_in(a.unit), x.numerical_value_ref_in(x.unit), b.numerical_value_ref_in(b.unit)),
|
||||||
|
common_reference(R * S, T)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -67,6 +67,11 @@ TEST_CASE("'fma()' on quantity changes the value and the dimension accordingly",
|
|||||||
REQUIRE(fma(1.0 * isq::length[m], 2.0 * one, 2.0 * isq::length[m]) == 4.0 * isq::length[m]);
|
REQUIRE(fma(1.0 * isq::length[m], 2.0 * one, 2.0 * isq::length[m]) == 4.0 * isq::length[m]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("'fma()' returns a common reference.", "[math][fma]")
|
||||||
|
{
|
||||||
|
REQUIRE(fma(isq::speed(10.0 * m / s), isq::time(2.0 * s), isq::height(42.0 * m)) == isq::length(62.0 * m));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_CASE("'pow<Num, Den>()' on quantity changes the value and the dimension accordingly", "[math][pow]")
|
TEST_CASE("'pow<Num, Den>()' on quantity changes the value and the dimension accordingly", "[math][pow]")
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user