Skip to content

Commit

Permalink
Merge branch 'master' into add_fma
Browse files Browse the repository at this point in the history
  • Loading branch information
NAThompson committed Dec 15, 2023
2 parents f32aafe + f1c3591 commit 83a9ce5
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 11 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v4
with:
python-version: 3.x
Expand All @@ -46,7 +48,7 @@ jobs:
mkdocs-material-
- name: Installing pip packages
run: |
pip install conan mkdocs-material mike
pip install conan mkdocs-material mkdocs-rss-plugin mike
- name: Prepare git
run: |
git config --global user.name github-actions
Expand Down
6 changes: 6 additions & 0 deletions docs/blog/.authors.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
authors:
mpusz:
name: Mateusz Pusz
description: Creator
avatar: https://avatars.githubusercontent.com/u/506260
url: https://github.com/mpusz
1 change: 1 addition & 0 deletions docs/blog/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Blog
130 changes: 130 additions & 0 deletions docs/blog/posts/2.0.0-released.md
Original file line number Diff line number Diff line change
@@ -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 changes: 50 additions & 0 deletions docs/blog/posts/kona-2023-report.md
Original file line number Diff line number Diff line change
@@ -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 changes: 10 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ theme:

# Plugins
plugins:
- blog
- rss:
match_path: blog/posts/.*
date_from_meta:
as_creation: date
categories:
- categories
- tags
- search
- tags:
tags_file: users_guide/examples/tags_index.md
Expand Down Expand Up @@ -108,6 +116,8 @@ nav:
- Quick Start: getting_started/quick_start.md
- Installation and Usage: getting_started/installation_and_usage.md
- FAQ: getting_started/faq.md
- Blog:
- blog/index.md
- User's Guide:
- Terms and Definitions: users_guide/terms_and_definitions.md
- Framework Basics:
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ conan
pre-commit
identify
mkdocs-material
mkdocs-rss-plugin
mike
15 changes: 5 additions & 10 deletions src/utility/include/mp-units/math.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,18 +144,12 @@ template<auto R, typename Rep>
* @param b: Addend
* @return Quantity: The nearest floating point representable to ax+b
*/

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),
get_quantity_spec(T))> auto
fma( // QuantityOf takes a QuantitySpec as an argument
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));
} && // 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)
fma(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)); } &&
(get_unit(R) * get_unit(S) == get_unit(T)) &&
(
requires {
fma(a.numerical_value_ref_in(a.unit), x.numerical_value_ref_in(x.unit),
Expand All @@ -168,7 +162,8 @@ fma( // QuantityOf takes a QuantitySpec as an argument
{
using std::fma;
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)};
}


Expand Down
1 change: 1 addition & 0 deletions test/unit_test/static/math_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ static_assert(compare(fma(2.0 * s, 3.0 * Hz, 1.0 * one), 7.0 * one));
static_assert(compare(fma(2.0 * one, 3.0 * m, 1.0 * m), 7.0 * m));
static_assert(compare(fma(2.0 * m, 3.0 * one, 1.0 * m), 7.0 * m));
static_assert(compare(fma(2 * m, 3.0f * m, 1.0 * m2), 7.0 * m2));
static_assert(compare(fma(isq::speed(10 * m / s), isq::time(2 * s), isq::height(42 * m)), isq::length(62 * m)));
static_assert(compare(pow<0>(2 * m), 1 * one));
static_assert(compare(pow<1>(2 * m), 2 * m));
static_assert(compare(pow<2>(2 * m), 4 * pow<2>(m), 4 * m2));
Expand Down

0 comments on commit 83a9ce5

Please sign in to comment.