Skip to content

Commit

Permalink
Merge branch 'master' into ref_docs
Browse files Browse the repository at this point in the history
  • Loading branch information
JohelEGP authored Dec 7, 2024
2 parents 2291b58 + 7eab29c commit aa7d3c6
Show file tree
Hide file tree
Showing 28 changed files with 379 additions and 296 deletions.
2 changes: 1 addition & 1 deletion docs/appendix/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@
[`derived dimension`](#derived-dimension){ #derived-dimension }

: - A [dimension](#dimension) of a [derived quantity](#derived-quantity).
- Implemented as an expression template being the result of the
- Implemented as a symbolic expression being the result of the
[dimension equation](#dimension-equation) on [base dimensions](#base-dimension).

[`dimension equation`](#dimension-equation){ #dimension-equation }
Expand Down
52 changes: 52 additions & 0 deletions docs/blog/posts/wrocław-2024-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
date: 2024-11-25
authors:
- mpusz
categories:
- WG21 Updates
comments: true
---

# Report from the Wrocław 2024 ISO C++ Committee meeting

The Wrocław 2024 meeting was another efficient step in the standardization of this library.
We've spent the entire day on the joint LEWGI and SG6 discussion and got lots of feedback.
We've also introduced `std::fixed_string` to LEWG for C++26.

<!-- more -->

## [P3045R4: Quantities and units library](https://wg21.link/p3045r4)

We have presented the following chapters of our proposal to LEWGI and SG6. We reviewed all
the usage examples, discussed composing symbols for derived dimensions and units, and looked into
formatting specifications for quantities. We also discussed the minimal scope of the proposal.

We got plenty of feedback on:

- the paper itself,
- naming of specific entities in the library,
- usage examples,
- text output and formatting.

We were also asked to extend the library to provide text output support for quantity points.

You can expect all of those changes to appear in the next release.


## [P30942R5: `std::basic_fixed_string`](https://wg21.link/p3094r5)

The paper was well received. However, Barry Revzin submitted
[P3380](https://wg21.link/p3380) paper in September. This started a discussion about the scope of
this proposal. Should we:

- limit it to just a non-mutating interface (as proposed) and maybe rename it to
  `std::string_literal`,
- add range slicing interface (as we support composition already),
- add some basic mutation interface through non-const `operator[]`,
- refactor to fully blown `std::inplace_string` if [P3380](https://wg21.link/p3380) successfully
progresses through EWG.

*[EWG]: Evolution Working Group
*[LEWG]: Library Evolution Working Group
*[SG6]: Study Group 6 - Numerics
*[LEWGI]: Study Group 18 - Library Evolution Working Group Incubator
2 changes: 1 addition & 1 deletion docs/getting_started/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ The above prints:

Some users could expect to see `42 kWh` or `42 kW h` in the output. It is not the case and for
a very good reason. As stated in
[Simplifying the resulting expression templates](../users_guide/framework_basics/interface_introduction.md#simplifying-the-resulting-expression-templates),
[Simplifying the resulting symbolic expressions](../users_guide/framework_basics/interface_introduction.md#simplifying-the-resulting-symbolic-expressions),
to be able to reason about and simplify units, the library needs to order them in an appropriate
order.

Expand Down
2 changes: 1 addition & 1 deletion docs/getting_started/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ To achieve this goal, several techniques are applied:
compile-times and the readability of error messages when compared to the traditional template
metaprogramming with [SFINAE](https://en.cppreference.com/w/cpp/language/sfinae),
- [usage of strong types for framework entities](../users_guide/framework_basics/interface_introduction.md#strong-types-instead-of-aliases) (instead of type aliases),
- [usage of expression templates](../users_guide/framework_basics/interface_introduction.md#expression-templates) to improve the readability of generated types,
- [usage of symbolic expressions](../users_guide/framework_basics/interface_introduction.md#symbolic-expressions) to improve the readability of generated types,
- limiting the number of template arguments to the bare minimum.

!!! important "Important: It is all about errors"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ ratio of `1` and does not output any textual symbol.
!!! important "Important: `one` is an identity"

A unit `one` is special in the entire type system of units as it is considered to be
[an identity operand in the unit expression templates](interface_introduction.md#identities).
[an identity operand in the unit symbolic expressions](interface_introduction.md#identities).
This means that, for example:

```cpp
Expand Down
14 changes: 7 additions & 7 deletions docs/users_guide/framework_basics/interface_introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ behind this is that:
Also, to prevent possible issues in compile-time logic, all of the library's entities must be
marked `final`. This prevents the users to derive own strong types from them, which would
prevent expression template simplification of equivalent entities.
prevent symbolic expressions simplification of equivalent entities.
## Strong types instead of aliases
Expand Down Expand Up @@ -103,14 +103,14 @@ inline constexpr struct joule final : named_unit<"J", newton * metre> {} joule;
```


## Expression templates
## Symbolic expressions

The previous chapter provided a rationale for not having predefined types for derived entities.
In many libraries, such an approach results in long and unreadable compilation errors, as
framework-generated types are typically far from being easy to read and understand.

The **mp-units** library greatly improves the user experience by extensively using
expression templates. Such expressions are used consistently throughout the entire library
symbolic expressions. Such expressions are used consistently throughout the entire library
to describe the results of:

- [dimension equation](../../appendix/glossary.md#dimension-equation) - the result is put into
Expand Down Expand Up @@ -169,7 +169,7 @@ constexpr auto my_unit = one / second;
constexpr auto my_unit = inverse(second);
```

Both cases will result in the same expression template being generated and put into the wrapper
Both cases will result in the same symbolic expression being generated and put into the wrapper
class template.


Expand All @@ -195,10 +195,10 @@ its unique representation in the library:
| `sqrt({identity})` or `pow<1, 2>({identity})` | `{identity}` |


### Simplifying the resulting expression templates
### Simplifying the resulting symbolic expressions

To limit the length and improve the readability of generated types, there are many rules to simplify
the resulting expression template.
the resulting symbolic expression.

1. **Ordering**

Expand Down Expand Up @@ -246,7 +246,7 @@ the resulting expression template.

Also, to prevent possible issues in compile-time logic, all of the library's entities must be
marked `final`. This prevents the users to derive own strong types from them, which would
prevent expression template simplification of equivalent entities.
prevent symbolic expression simplification of equivalent entities.

4. **Repacking**

Expand Down
2 changes: 1 addition & 1 deletion docs/users_guide/framework_basics/systems_of_units.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ All of the above quantities are equivalent and mean exactly the same.

The above code example may give the impression that the order of components in a derived
unit is determined by the multiplication order. This is not the case. As stated in
[Simplifying the resulting expression templates](interface_introduction.md#simplifying-the-resulting-expression-templates),
[Simplifying the resulting symbolic expressions](interface_introduction.md#simplifying-the-resulting-symbolic-expressions),
to be able to reason about and simplify units, the library needs to order them in an
appropriate order. This will affect the order of components in a resulting type and
text output.
Expand Down
2 changes: 1 addition & 1 deletion src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ add_mp_units_module(
include/mp-units/framework/customization_points.h
include/mp-units/framework/dimension.h
include/mp-units/framework/dimension_concepts.h
include/mp-units/framework/expression_template.h
include/mp-units/framework/quantity.h
include/mp-units/framework/quantity_cast.h
include/mp-units/framework/quantity_concepts.h
Expand All @@ -67,6 +66,7 @@ add_mp_units_module(
include/mp-units/framework/reference_concepts.h
include/mp-units/framework/representation_concepts.h
include/mp-units/framework/symbol_text.h
include/mp-units/framework/symbolic_expression.h
include/mp-units/framework/system_reference.h
include/mp-units/framework/unit.h
include/mp-units/framework/unit_concepts.h
Expand Down
65 changes: 9 additions & 56 deletions src/core/include/mp-units/bits/get_associated_quantity.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@

#pragma once

#include <mp-units/framework/expression_template.h>
#include <mp-units/framework/quantity_spec.h>
#include <mp-units/framework/symbolic_expression.h>
#include <mp-units/framework/unit_concepts.h>

namespace mp_units {
Expand All @@ -34,73 +34,26 @@ struct common_unit;
namespace detail {

template<AssociatedUnit U>
[[nodiscard]] consteval auto all_are_kinds(U);
[[nodiscard]] consteval auto get_associated_quantity(U u);

template<typename U, auto... Vs>
[[nodiscard]] consteval auto all_are_kinds(power<U, Vs...>)
{
return all_are_kinds(U{});
}

template<typename... Nums, typename... Dens>
[[nodiscard]] consteval bool all_are_kinds(type_list<Nums...>, type_list<Dens...>)
{
return (... && all_are_kinds(Nums{})) && (... && all_are_kinds(Dens{}));
}

template<AssociatedUnit U>
[[nodiscard]] consteval auto all_are_kinds(U)
template<typename... Us>
[[nodiscard]] consteval auto get_associated_quantity_impl(common_unit<Us...>)
{
if constexpr (requires { U::_quantity_spec_; })
return QuantityKindSpec<MP_UNITS_NONCONST_TYPE(U::_quantity_spec_)>;
else if constexpr (requires { U::_reference_unit_; })
return all_are_kinds(U::_reference_unit_);
else if constexpr (requires { typename U::_num_; }) {
return all_are_kinds(typename U::_num_{}, typename U::_den_{});
}
return get_common_quantity_spec(get_associated_quantity(Us{})...);
}

template<AssociatedUnit U>
[[nodiscard]] consteval auto determine_associated_quantity(U u);

template<AssociatedUnit U>
using to_quantity_spec = decltype(determine_associated_quantity(U{}));

template<typename... Us>
[[nodiscard]] consteval auto determine_associated_quantity_impl(common_unit<Us...>)
{
return get_common_quantity_spec(determine_associated_quantity(Us{})...);
}
using to_quantity_spec = decltype(get_associated_quantity(U{}));

template<AssociatedUnit U>
[[nodiscard]] consteval auto determine_associated_quantity_impl(U u)
[[nodiscard]] consteval auto get_associated_quantity_impl(U u)
{
if constexpr (requires { U::_quantity_spec_; })
return remove_kind(U::_quantity_spec_);
else if constexpr (requires { U::_reference_unit_; })
return determine_associated_quantity(U::_reference_unit_);
else if constexpr (requires { typename U::_num_; }) {
return get_associated_quantity(U::_reference_unit_);
else if constexpr (requires { typename U::_num_; })
return expr_map<to_quantity_spec, derived_quantity_spec, struct dimensionless>(u);
}
}

template<AssociatedUnit U>
constexpr auto determine_associated_quantity_result = determine_associated_quantity_impl(U{});

template<AssociatedUnit U>
[[nodiscard]] consteval auto determine_associated_quantity(U)
{
return determine_associated_quantity_result<U>;
}

template<AssociatedUnit U>
[[nodiscard]] consteval auto get_associated_quantity_impl(U u)
{
constexpr bool all_kinds = all_are_kinds(U{});
if constexpr (all_kinds)
return kind_of<determine_associated_quantity(U{})>;
else
return determine_associated_quantity(u);
}

template<AssociatedUnit U>
Expand Down
2 changes: 1 addition & 1 deletion src/core/include/mp-units/bits/unit_magnitude.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
#include <mp-units/ext/prime.h>
#include <mp-units/ext/type_traits.h>
#include <mp-units/framework/customization_points.h>
#include <mp-units/framework/expression_template.h>
#include <mp-units/framework/symbol_text.h>
#include <mp-units/framework/symbolic_expression.h>
#include <mp-units/framework/unit_magnitude_concepts.h>
#include <mp-units/framework/unit_symbol_formatting.h>

Expand Down
2 changes: 1 addition & 1 deletion src/core/include/mp-units/framework.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
#include <mp-units/framework/customization_points.h>
#include <mp-units/framework/dimension.h>
#include <mp-units/framework/dimension_concepts.h>
#include <mp-units/framework/expression_template.h>
#include <mp-units/framework/quantity.h>
#include <mp-units/framework/quantity_cast.h>
#include <mp-units/framework/quantity_concepts.h>
Expand All @@ -39,6 +38,7 @@
#include <mp-units/framework/reference.h>
#include <mp-units/framework/representation_concepts.h>
#include <mp-units/framework/symbol_text.h>
#include <mp-units/framework/symbolic_expression.h>
#include <mp-units/framework/system_reference.h>
#include <mp-units/framework/unit.h>
#include <mp-units/framework/unit_concepts.h>
Expand Down
4 changes: 2 additions & 2 deletions src/core/include/mp-units/framework/dimension.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
#include <mp-units/ext/inplace_vector.h>
#include <mp-units/ext/type_traits.h>
#include <mp-units/framework/dimension_concepts.h>
#include <mp-units/framework/expression_template.h>
#include <mp-units/framework/symbol_text.h>
#include <mp-units/framework/symbolic_expression.h>

#ifndef MP_UNITS_IN_MODULE_INTERFACE
#include <mp-units/ext/contracts.h>
Expand Down Expand Up @@ -122,7 +122,7 @@ struct base_dimension : detail::dimension_interface {
* Derived dimension is an expression of the dependence of a quantity on the base quantities of a system of quantities
* as a product of powers of factors corresponding to the base quantities, omitting any numerical factors.
*
* Instead of using a raw list of exponents this library decided to use expression template syntax to make types
* Instead of using a raw list of exponents this library decided to use symbolic expression syntax to make types
* more digestable for the user. The positive exponents are ordered first and all negative exponents are put as a list
* into the `per<...>` class template. If a power of exponent is different than `1` the dimension type is enclosed in
* `power<Dim, Num, Den>` class template. Otherwise, it is just put directly in the list without any wrapper. There
Expand Down
2 changes: 1 addition & 1 deletion src/core/include/mp-units/framework/dimension_concepts.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
// IWYU pragma: private, include <mp-units/framework.h>
#include <mp-units/bits/module_macros.h>
#include <mp-units/ext/type_traits.h>
#include <mp-units/framework/expression_template.h>
#include <mp-units/framework/symbol_text.h>
#include <mp-units/framework/symbolic_expression.h>

namespace mp_units {

Expand Down
Loading

0 comments on commit aa7d3c6

Please sign in to comment.