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 Oct 31, 2024
2 parents 0e93d30 + 93e112f commit b28abe1
Show file tree
Hide file tree
Showing 15 changed files with 102 additions and 89 deletions.
9 changes: 7 additions & 2 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ jobs:
- name: Installing pip dependencies
run: |
pip install conan mkdocs-material mkdocs-rss-plugin mkdocs-material[imaging] mkdocs-exclude mike
- name: Building docs
- name: Building docs for a released version
if: startsWith(github.event.ref, 'refs/tags/v')
run: |
mike deploy --push --update-aliases `conan inspect . | sed -n -r 's/version: ([0-9]+.[0-9]+).[0-9]+/\1/p'` latest
mike deploy --push --update-aliases `conan inspect . | sed -n -r 's/version: ([0-9]+.[0-9]+).[0-9]+/\1/p'`
- name: Building docs for a development version
if: ${{!startsWith(github.event.ref, 'refs/tags/v')}}
run: |
mike deploy --push --update-aliases HEAD latest
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ repos:
- id: trailing-whitespace
- id: end-of-file-fixer
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v18.1.8
rev: v19.1.2
hooks:
- id: clang-format
- repo: https://github.com/cheshirekow/cmake-format-precommit
Expand Down
20 changes: 20 additions & 0 deletions docs/.overrides/api_reference.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{% extends "main.html" %}

{% block htmltitle %}
{% if page.meta and page.meta.title %}
<title>{{ page.meta.title }}</title>
{% elif page.title and not page.is_homepage %}
<title>{{ page.title | striptags }}</title>
{% else %}
<title>{{ config.site_name }}</title>
{% endif %}
{% endblock %}

{% block content %}
{% include "partials/api_ref_content.html" %}
{% endblock %}

{% block extrahead %}
<style>.md-content__button {display:none !important}; </style>
<style>.md-header__topic {font-weight:700 !important}</style>
{% endblock %}
11 changes: 11 additions & 0 deletions docs/.overrides/partials/api_ref_content.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{% if "material/tags" in config.plugins and tags %}
{% include "partials/tags.html" %}
{% endif %}
{% include "partials/actions.html" %}
{% if "\x3ch1" not in page.content %}
<!--h1>{{ page.title | d(config.site_name, true)}}</h1-->
{% endif %}
{{ page.content }}
{% include "partials/source-file.html" %}
{% include "partials/feedback.html" %}
{% include "partials/comments.html" %}
26 changes: 10 additions & 16 deletions docs/api_reference.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
---
title: API Reference - mp-units
template: api_reference.html
hide:
- navigation
- toc
Expand Down Expand Up @@ -37,17 +39,12 @@ apiIframe = document.getElementById('apiIframe');
hash = window.location.hash;
if (hash.length == 0) {
// sets default hash for the API Reference
hash = "#full";
hash = "#index.html";
history.pushState(null, "", hash);
}

// set the iframe source based on the hash in the URL
if (hash.startsWith("#wg21.link/")) {
apiIframe.src = "https://" + hash.slice(1);
apiIframe.height = 900;
}
else
apiIframe.src = "gen/" + hash.slice(1) + ".html";
apiIframe.src = "gen/" + hash.slice(1);

// receives content height from the subpage displayed in the iframe
// works only for the pages in the same domain as the main docs
Expand All @@ -57,18 +54,15 @@ iFrameResize({
// obtains the link URL clicked in the subpage
onMessage: function(messageData) {
url = messageData.message;
if (url.startsWith("https://wg21.link/")) {
hash = '#' + messageData.message.replace("https://", "");
if (url.search("api_reference/gen") == -1) {
window.open(url);
}
else {
pos = messageData.message.indexOf('#');
if(pos == -1) {
pos = messageData.message.lastIndexOf('/');
}
hash = '#' + messageData.message.slice(pos + 1);
pos_start = messageData.message.lastIndexOf('/');
hash = '#' + messageData.message.slice(pos_start + 1)
history.pushState(null, "", hash);
window.location.reload();
}
history.pushState(null, "", hash);
window.location.reload();
}
},'#apiIframe')
</script>
2 changes: 1 addition & 1 deletion docs/blog/posts/isq-part-1-introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ In this series, we will describe:

- Part 1 - Introduction
- [Part 2 - Problems when ISQ is not used](isq-part-2-problems-when-isq-is-not-used.md)
- [Part 3 - Modelling ISQ](isq-part-3-modelling-isq.md)
- [Part 3 - Modeling ISQ](isq-part-3-modeling-isq.md)
- [Part 4 - Implementing ISQ](isq-part-4-implemeting-isq.md)

## Terms and Definitions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ library on just units or dimensions.

- [Part 1 - Introduction](isq-part-1-introduction.md)
- Part 2 - Problems when ISQ is not used
- [Part 3 - Modelling ISQ](isq-part-3-modelling-isq.md)
- [Part 3 - Modeling ISQ](isq-part-3-modeling-isq.md)
- [Part 4 - Implementing ISQ](isq-part-4-implemeting-isq.md)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ categories:
comments: true
---

# International System of Quantities (ISQ): Part 3 - Modelling ISQ
# International System of Quantities (ISQ): Part 3 - Modeling ISQ

The physical units libraries on the market typically only focus on modeling one or more systems
of units. However, as we have learned, this is not the only system kind to model. Another,
Expand All @@ -24,7 +24,7 @@ language.

- [Part 1 - Introduction](isq-part-1-introduction.md)
- [Part 2 - Problems when ISQ is not used](isq-part-2-problems-when-isq-is-not-used.md)
- Part 3 - Modelling ISQ
- Part 3 - Modeling ISQ
- [Part 4 - Implementing ISQ](isq-part-4-implemeting-isq.md)


Expand Down
4 changes: 2 additions & 2 deletions docs/blog/posts/isq-part-4-implemeting-isq.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ language, and we will point out some of the first issues that stand in our way.
<!-- more -->

In the previous article, we have already introduced a notion of quantity kind, provided `kind_of<>`
specifier, and described how it helps in the modelling of the system of units (e.g., SI).
specifier, and described how it helps in the modeling of the system of units (e.g., SI).

Now, it is time to see how we can implement hierarchies of quantities of the same kind.

Expand All @@ -25,7 +25,7 @@ Now, it is time to see how we can implement hierarchies of quantities of the sam

- [Part 1 - Introduction](isq-part-1-introduction.md)
- [Part 2 - Problems when ISQ is not used](isq-part-2-problems-when-isq-is-not-used.md)
- [Part 3 - Modelling ISQ](isq-part-3-modelling-isq.md)
- [Part 3 - Modeling ISQ](isq-part-3-modeling-isq.md)
- Part 4 - Implementing ISQ


Expand Down
10 changes: 5 additions & 5 deletions docs/blog/posts/isq-part-5-benefits.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ that does not use such abstraction to implement a units library.

In this article we will present how our ISQ model elegantly addresses the issues from the
[Part 2](isq-part-2-problems-when-isq-is-not-used.md) of our series that were not covered already
in [Part 3](isq-part-3-modelling-isq.md).
in [Part 3](isq-part-3-modeling-isq.md).

<!-- more -->

## Articles from this series

- [Part 1 - Introduction](isq-part-1-introduction.md)
- [Part 2 - Problems when ISQ is not used](isq-part-2-problems-when-isq-is-not-used.md)
- [Part 3 - Modelling ISQ](isq-part-3-modelling-isq.md)
- [Part 3 - Modeling ISQ](isq-part-3-modeling-isq.md)
- [Part 4 - Implementing ISQ](isq-part-4-implemeting-isq.md)
- Part 5 - Benefits

Expand Down Expand Up @@ -121,7 +121,7 @@ std::cout << price_usd << " -> " << price_euro << "\n";

## Derived quantities of the same dimension but different kinds

Up until now, the discussed issues did not actually require modelling of the ISQ. Introduction
Up until now, the discussed issues did not actually require modeling of the ISQ. Introduction
of physical dimensions would be enough, and indeed, this is what most of the libraries on the
market do. However, we have more interesting challenges to solve as well.

Expand Down Expand Up @@ -236,7 +236,7 @@ Box my_box3(horizontal_length(2 * m), isq::width(3 * m), isq::height(1 * m));
## Various kinds of dimensionless quantities

Most of the quantities hierarchies describe only one kind. There are some exceptions, though.
One of them is a [hierarchy of _dimensionless_ quantities](#modeling-a-hierarchy-of-kind-dimensionless).
One of them is a [hierarchy of _dimensionless_ quantities](isq-part-4-implemeting-isq.md#modeling-a-hierarchy-of-kind-dimensionless).
This tree defines quantities that denote:

- counts (_storage capacity_),
Expand Down Expand Up @@ -425,5 +425,5 @@ Transport Time is: 8.997726 s

## To be continued...

In the next part of this series, we will discuss the challenges and issues related to the modelling
In the next part of this series, we will discuss the challenges and issues related to the modeling
of the ISQ with a programming language.
23 changes: 15 additions & 8 deletions docs/users_guide/framework_basics/quantity_arithmetics.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,26 @@ static_assert(isq::radius(1 * m) - 0.5 * m == isq::radius(0.5 * m));
left-hand-side argument type:
```cpp
static_assert((1 * m += 1.5 * m) == 2 * m);
static_assert((1 * m += 1.5 * km) == 1501 * m);
static_assert((1 * m += 1 * km) == 1001 * m);
static_assert((isq::length(1 * m) += isq::height(1 * m)) == isq::length(1 * m));
static_assert((isq::height(1.5 * m) -= 1 * m) == isq::height(0.5 * m));
```
If we will break typical library's convertibility rules, the following code will not compile:
```cpp
quantity q1 = 1 * km += 1 * m; // Compile-time error
quantity q2 = isq::height(1 * m) += isq::length(1 * m) // Compile-time error
quantity q1 = 1 * m -= 0.5 * m; // Compile-time error(1)
quantity q2 = 1 * km += 1 * m; // Compile-time error(2)
quantity q3 = isq::height(1 * m) += isq::length(1 * m); // Compile-time error(3)
```
1. Conversion of the floating-point to integral representation type is
[considered narrowing](value_conversions.md).
2. Conversion of quantity with integral representation type from a unit of a higher resolution
to the one with a lower resolution is [considered narrowing](value_conversions.md).
3. Conversion from a more generic quantity type to a more specific one is
[considered unsafe](simple_and_typed_quantities.md#quantity_cast-to-force-unsafe-conversions).
## Multiplication and division
Expand All @@ -118,12 +125,12 @@ static_assert(isq::height(3 * m) * 0.5 == isq::height(1.5 * m));

!!! note

Unless we use a compound assignment operator, in which case we will always result with the type
of the left-hand-side argument and the value consistent to the behavior of the underlying
representation types:
Unless we use a compound assignment operator, in which case we always have to result with
the type of the left-hand-side argument. This, together with the fact that this library
tries to prevent truncation of a quantity value means, that the following does not compile:

```cpp
static_assert((isq::height(3 * m) *= 0.5) == isq::height(1 * m));
quantity q = isq::height(3 * m) *= 0.5; // Compile-time error
```

However, suppose we multiply or divide quantities of the same or different types or we divide a raw
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 @@ -196,7 +196,7 @@ For some units, a magnitude might also be irrational. The best example here is a
is defined using a floating-point magnitude having a factor of the number π (Pi):
```cpp
inline constexpr struct pi final : mag_constant<symbol_text{u8"π", "pi"}, std::numbers::pi_v<long double>> {
inline constexpr struct pi final : mag_constant<symbol_text{u8"π", "pi"}, std::numbers::pi_v<long double>> {} pi;
inline constexpr auto π = pi;
```

Expand Down
41 changes: 17 additions & 24 deletions src/core/include/mp-units/framework/quantity.h
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ class quantity {

// compound assignment operators
template<detail::Forwarding<quantity> Q, auto R2, typename Rep2>
requires detail::QuantityConvertibleTo<quantity<R2, rep>, quantity> && requires(rep a, Rep2 b) {
requires detail::QuantityConvertibleTo<quantity<R2, Rep2>, quantity> && requires(rep a, Rep2 b) {
{ a += b } -> std::same_as<rep&>;
}
friend constexpr decltype(auto) operator+=(Q&& lhs, const quantity<R2, Rep2>& rhs)
Expand All @@ -389,7 +389,7 @@ class quantity {
}

template<detail::Forwarding<quantity> Q, auto R2, typename Rep2>
requires detail::QuantityConvertibleTo<quantity<R2, rep>, quantity> && requires(rep a, Rep2 b) {
requires detail::QuantityConvertibleTo<quantity<R2, Rep2>, quantity> && requires(rep a, Rep2 b) {
{ a -= b } -> std::same_as<rep&>;
}
friend constexpr decltype(auto) operator-=(Q&& lhs, const quantity<R2, Rep2>& rhs)
Expand All @@ -402,7 +402,7 @@ class quantity {
}

template<detail::Forwarding<quantity> Q, auto R2, typename Rep2>
requires detail::QuantityConvertibleTo<quantity<R2, rep>, quantity> && (!treat_as_floating_point<rep>) &&
requires detail::QuantityConvertibleTo<quantity<R2, Rep2>, quantity> && (!treat_as_floating_point<rep>) &&
requires(rep a, Rep2 b) {
{ a %= b } -> std::same_as<rep&>;
}
Expand All @@ -417,7 +417,7 @@ class quantity {
return std::forward<Q>(lhs);
}

template<detail::Forwarding<quantity> Q, typename Value>
template<detail::Forwarding<quantity> Q, detail::ValuePreservingTo<Rep> Value>
requires(!Quantity<Value>) && requires(rep a, Value b) {
{ a *= b } -> std::same_as<rep&>;
}
Expand All @@ -430,19 +430,16 @@ class quantity {
}

template<detail::Forwarding<quantity> Q1, QuantityOf<dimensionless> Q2>
requires(Q2::unit == ::mp_units::one) && requires(rep a, Q2::rep b) {
{ a *= b } -> std::same_as<rep&>;
}
requires(Q2::unit == ::mp_units::one) && detail::ValuePreservingTo<typename Q2::rep, Rep> &&
requires(rep a, Q2::rep b) {
{ a *= b } -> std::same_as<rep&>;
}
friend constexpr decltype(auto) operator*=(Q1&& lhs, const Q2& rhs)
{
// TODO use *= when compiler bug is resolved:
// https://developercommunity.visualstudio.com/t/Discrepancy-in-Behavior-of-operator-an/10732445
lhs.numerical_value_is_an_implementation_detail_ =
lhs.numerical_value_is_an_implementation_detail_ * rhs.numerical_value_is_an_implementation_detail_;
return std::forward<Q1>(lhs);
return std::forward<Q1>(lhs) *= rhs.numerical_value_is_an_implementation_detail_;
}

template<detail::Forwarding<quantity> Q, typename Value>
template<detail::Forwarding<quantity> Q, detail::ValuePreservingTo<Rep> Value>
requires(!Quantity<Value>) && requires(rep a, Value b) {
{ a /= b } -> std::same_as<rep&>;
}
Expand All @@ -456,17 +453,13 @@ class quantity {
}

template<detail::Forwarding<quantity> Q1, QuantityOf<dimensionless> Q2>
requires(Q2::unit == ::mp_units::one) && requires(rep a, Q2::rep b) {
{ a /= b } -> std::same_as<rep&>;
}
requires(Q2::unit == ::mp_units::one) && detail::ValuePreservingTo<typename Q2::rep, Rep> &&
requires(rep a, Q2::rep b) {
{ a /= b } -> std::same_as<rep&>;
}
friend constexpr decltype(auto) operator/=(Q1&& lhs, const Q2& rhs)
{
MP_UNITS_EXPECTS_DEBUG(rhs != rhs.zero());
// TODO use /= when compiler bug is resolved:
// https://developercommunity.visualstudio.com/t/Discrepancy-in-Behavior-of-operator-an/10732445
lhs.numerical_value_is_an_implementation_detail_ =
lhs.numerical_value_is_an_implementation_detail_ / rhs.numerical_value_is_an_implementation_detail_;
return std::forward<Q1>(lhs);
return std::forward<Q1>(lhs) /= rhs.numerical_value_is_an_implementation_detail_;
}

// binary operators on quantities
Expand Down Expand Up @@ -646,8 +639,8 @@ template<Representation Value>
explicit(false) quantity(Value) -> quantity<one, Value>;

template<QuantityLike Q>
explicit(quantity_like_traits<Q>::explicit_import)
quantity(Q) -> quantity<quantity_like_traits<Q>::reference, typename quantity_like_traits<Q>::rep>;
explicit(quantity_like_traits<Q>::explicit_import) quantity(Q)
-> quantity<quantity_like_traits<Q>::reference, typename quantity_like_traits<Q>::rep>;

MP_UNITS_EXPORT_END

Expand Down
3 changes: 1 addition & 2 deletions src/systems/include/mp-units/systems/si/chrono.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,7 @@ struct quantity_like_traits<std::chrono::duration<Rep, Period>> {
using rep = Rep;
using T = std::chrono::duration<Rep, Period>;

[[nodiscard]] static constexpr rep to_numerical_value(const T& q) noexcept(
std::is_nothrow_copy_constructible_v<rep>)
[[nodiscard]] static constexpr rep to_numerical_value(const T& q) noexcept(std::is_nothrow_copy_constructible_v<rep>)
{
return q.count();
}
Expand Down
Loading

0 comments on commit b28abe1

Please sign in to comment.