From 43ea6adc647d68cfd01ee4b8520f755e28541588 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 5 Nov 2024 08:00:10 +0100 Subject: [PATCH 01/15] refactor: `TagType` renamed to `SymbolicConstant` --- src/core/include/mp-units/ext/type_traits.h | 2 +- src/core/include/mp-units/framework/dimension_concepts.h | 2 +- src/core/include/mp-units/framework/magnitude_concepts.h | 2 +- src/core/include/mp-units/framework/quantity_point_concepts.h | 2 +- src/core/include/mp-units/framework/quantity_spec_concepts.h | 2 +- src/core/include/mp-units/framework/unit_concepts.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/include/mp-units/ext/type_traits.h b/src/core/include/mp-units/ext/type_traits.h index 01d3780d2..70b9523c7 100644 --- a/src/core/include/mp-units/ext/type_traits.h +++ b/src/core/include/mp-units/ext/type_traits.h @@ -196,7 +196,7 @@ template typename T, typename T1, typename T2, typename... Ts> namespace detail { template -concept TagType = std::is_empty_v && std::is_final_v; +concept SymbolicConstant = std::is_empty_v && std::is_final_v; } diff --git a/src/core/include/mp-units/framework/dimension_concepts.h b/src/core/include/mp-units/framework/dimension_concepts.h index 6e3c653b6..28914f9ab 100644 --- a/src/core/include/mp-units/framework/dimension_concepts.h +++ b/src/core/include/mp-units/framework/dimension_concepts.h @@ -42,7 +42,7 @@ struct dimension_interface; * Satisfied by all dimension types in the library. */ MP_UNITS_EXPORT template -concept Dimension = detail::TagType && std::derived_from; +concept Dimension = detail::SymbolicConstant && std::derived_from; MP_UNITS_EXPORT template struct base_dimension; diff --git a/src/core/include/mp-units/framework/magnitude_concepts.h b/src/core/include/mp-units/framework/magnitude_concepts.h index 586c25e42..a979923a4 100644 --- a/src/core/include/mp-units/framework/magnitude_concepts.h +++ b/src/core/include/mp-units/framework/magnitude_concepts.h @@ -47,7 +47,7 @@ MP_UNITS_EXPORT template struct mag_constant; MP_UNITS_EXPORT template -concept MagConstant = detail::TagType && is_derived_from_specialization_of_v; +concept MagConstant = detail::SymbolicConstant && is_derived_from_specialization_of_v; template struct magnitude; diff --git a/src/core/include/mp-units/framework/quantity_point_concepts.h b/src/core/include/mp-units/framework/quantity_point_concepts.h index 91409cd6e..08834c9ae 100644 --- a/src/core/include/mp-units/framework/quantity_point_concepts.h +++ b/src/core/include/mp-units/framework/quantity_point_concepts.h @@ -65,7 +65,7 @@ struct point_origin_interface; * Satisfied by either quantity points or by all types derived from `absolute_point_origin` class template. */ MP_UNITS_EXPORT template -concept PointOrigin = detail::TagType && std::derived_from; +concept PointOrigin = detail::SymbolicConstant && std::derived_from; /** * @brief A concept matching all quantity point origins for a specified quantity type in the library diff --git a/src/core/include/mp-units/framework/quantity_spec_concepts.h b/src/core/include/mp-units/framework/quantity_spec_concepts.h index e7d4745f9..6e7e0934f 100644 --- a/src/core/include/mp-units/framework/quantity_spec_concepts.h +++ b/src/core/include/mp-units/framework/quantity_spec_concepts.h @@ -37,7 +37,7 @@ struct quantity_spec_interface_base; } MP_UNITS_EXPORT template -concept QuantitySpec = detail::TagType && std::derived_from; +concept QuantitySpec = detail::SymbolicConstant && std::derived_from; MP_UNITS_EXPORT #if MP_UNITS_API_NO_CRTP diff --git a/src/core/include/mp-units/framework/unit_concepts.h b/src/core/include/mp-units/framework/unit_concepts.h index cf4f90b12..c66f0b729 100644 --- a/src/core/include/mp-units/framework/unit_concepts.h +++ b/src/core/include/mp-units/framework/unit_concepts.h @@ -43,7 +43,7 @@ struct unit_interface; * Satisfied by all unit types provided by the library. */ MP_UNITS_EXPORT template -concept Unit = detail::TagType && std::derived_from; +concept Unit = detail::SymbolicConstant && std::derived_from; template requires(M != magnitude<>{} && M != mag<1>) From 65a3c80a5fce7c25d0b569254c38ee89be9e413e Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 5 Nov 2024 08:06:04 +0100 Subject: [PATCH 02/15] refactor: `max` used in one of the `explode` overloads --- src/core/include/mp-units/framework/quantity_spec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/include/mp-units/framework/quantity_spec.h b/src/core/include/mp-units/framework/quantity_spec.h index 802cece17..bfe9d0b2b 100644 --- a/src/core/include/mp-units/framework/quantity_spec.h +++ b/src/core/include/mp-units/framework/quantity_spec.h @@ -737,7 +737,7 @@ template den ? num : den; + constexpr auto max_compl = max(num, den); if constexpr (max_compl == Complexity || ((num >= den && !requires { explode_to_equation(Num{}); }) || (num < den && !requires { explode_to_equation(Den{}); }))) From 2892fd83b0551cd6ccbb63d448b3474e7c1c66b6 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 5 Nov 2024 08:06:45 +0100 Subject: [PATCH 03/15] test: more `get_common_quantity_spec` tests added --- test/static/quantity_spec_test.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/static/quantity_spec_test.cpp b/test/static/quantity_spec_test.cpp index 73778da6b..1c7bba626 100644 --- a/test/static/quantity_spec_test.cpp +++ b/test/static/quantity_spec_test.cpp @@ -815,6 +815,10 @@ static_assert(get_common_quantity_spec(speed, length / time) == speed); static_assert(get_common_quantity_spec(length / time, speed) == speed); static_assert(get_common_quantity_spec(area, length* length) == area); static_assert(get_common_quantity_spec(length * length, area) == area); +static_assert(get_common_quantity_spec(frequency, inverse(time)) == inverse(time)); +static_assert(get_common_quantity_spec(inverse(time), frequency) == inverse(time)); +static_assert(get_common_quantity_spec(frequency, inverse(period_duration)) == frequency); +static_assert(get_common_quantity_spec(inverse(period_duration), frequency) == frequency); static_assert(get_common_quantity_spec(kinetic_energy, mass* pow<2>(length) / pow<2>(time)) == kinetic_energy); static_assert(get_common_quantity_spec(mass * pow<2>(length) / pow<2>(time), kinetic_energy) == kinetic_energy); static_assert(get_common_quantity_spec(gravitational_potential_energy, mass* acceleration_of_free_fall* height) == From 16dbce6948a8704b2d03b312cb0a2ef941506d69 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 5 Nov 2024 17:25:45 +0100 Subject: [PATCH 04/15] docs: 2.4.0 release announcement updated --- docs/blog/posts/2.4.0-released.md | 119 ++++++++++++++++++++++++++---- 1 file changed, 105 insertions(+), 14 deletions(-) diff --git a/docs/blog/posts/2.4.0-released.md b/docs/blog/posts/2.4.0-released.md index 4b8f35205..714379b48 100644 --- a/docs/blog/posts/2.4.0-released.md +++ b/docs/blog/posts/2.4.0-released.md @@ -1,6 +1,6 @@ --- draft: true -date: 2024-10-27 +date: 2024-11-05 authors: - mpusz categories: @@ -18,7 +18,7 @@ This release was unexpected. We planned a significant new feature to happen next 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 +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). @@ -32,7 +32,7 @@ in this release, we moved all of them to the `isq` namespace (:boom: **breaking 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`). +by IEC (e.g., `var`, `erlang`, `bit`, or ``baud`). !!! note @@ -40,16 +40,16 @@ by IEC (e.g. `var`, `erlang`, `bit`, or ``baud`). 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:). +alternative names `phase_velocity` and `group_velocity`. This is misleading as _velocity_ is +typically considered a vector quantity. It is why those `XXX_velocity` aliases were removed from +the ISO standard and from **mp-units** library (: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: +this might not be entirely correct. Some quantities require a specific 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`). @@ -74,10 +74,10 @@ From the very beginning, the text output of symbols could be formatted in two di 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:). +During the recent SG16 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: +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. @@ -87,6 +87,8 @@ From now on we will provide the following: The old identifiers and formatting options are now deprecated and will be removed in future releases. +*[SG16]: WG21 Unicode Study Group + ## `char_traits` removed from `fixed_string` @@ -95,7 +97,7 @@ During the same SG16 meeting, the room was strongly against providing `char_trai (:boom: **breaking change** :boom:). -## Improved units text output +## 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 `=`. @@ -154,7 +156,7 @@ prints: 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. +One more change that we can see above is that litre now use 'L' instead of 'l' for its 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 @@ -188,7 +190,9 @@ The example above introduced something interesting: a `π` identifier for a vari 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. +In this release, we've added Unicode identifiers support not only for `π` magnitude constant +but also for unit symbols. + Now we can type the following: === "With UTF-8 glyphs" @@ -208,3 +212,90 @@ Now we can type the following: 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. + + +## Convertibility with `QuantityLike` and `QuantityPointLike` entities + +In this release, we decided to fine-tune further the traits that customize the conversion between +custom quantity and quantity point types and the ones provided with **mp-units** +(:boom: **breaking change** :boom:). + +Previously, `to_numerical_value` and `from_numerical_value` returned a type wrapped in a special +tag type describing the conversion type (explicit or implicit). + +This was a novel and experimental approach. Finally, we decided not to do it and used a bit more +verbose but a more standard solution. From now on, we need to provide two additional static data +members of type `bool`: + +- `explicit_import` - `true` means that the conversion to the **mp-units** abstraction is explicit, +- `explicit_export` - `true` means that the conversion from the **mp-units** abstraction is + explicit. + +=== "Now" + + ```cpp + template<> + struct mp_units::quantity_point_like_traits { + static constexpr auto reference = si::second; + static constexpr auto point_origin = default_point_origin(reference); + static constexpr bool explicit_import = false; + static constexpr bool explicit_export = true; + using rep = decltype(Timestamp::seconds); + + static constexpr rep to_numerical_value(Timestamp ts) + { + return ts.seconds; + } + + static constexpr Timestamp from_numerical_value(rep v) + { + return Timestamp(v); + } + }; + ``` + +=== "Before" + + ```cpp + template<> + struct mp_units::quantity_point_like_traits { + static constexpr auto reference = si::second; + static constexpr auto point_origin = default_point_origin(reference); + using rep = decltype(Timestamp::seconds); + + static constexpr convert_implicitly to_numerical_value(Timestamp ts) + { + return ts.seconds; + } + + static constexpr convert_explicitly from_numerical_value(rep v) + { + return Timestamp(v); + } + }; + ``` + + +## Symbolic constants implementation should be _implementation-defined_ + +In the process of writing API Reference, we decided to hide all the metadata associated with +symbolic constants - tag types used to define units, dimensions, quantity specification, etc. +(:boom: **breaking change** :boom:). + +All the types and values exposed by such types are needed only in the implementation details +of the library. Users should not need them. Hiding those and making them +_implementation-defined_ gives other vendors the freedom to choose different ways to implement +features of this library in their codebases. + +!!! important + + Based on [Hyrum's Law](https://www.hyrumslaw.com/) some users may depend on this + information already, and this release will break their code. + + If that is the case for you, we would love to hear about your use case and its rationale. + It may mean that we should either: + + - extend the library's functionality to support your use case out of the box and keep those + members hidden, + - restore public visibility of such members and enforce this in the API Reference so that all + the users of various library implementations may use them in the same way as you. From 98f173993d36a715c5fe8036665985227ac1cca0 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 5 Nov 2024 17:26:01 +0100 Subject: [PATCH 05/15] docs: CHANGELOG udpated --- CHANGELOG.md | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a9be830e..61e5ac46e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ - feat: tag types are now required to be empty - feat: magnitude text now obeys formatting parameters and knows how to print constants - feat: added support for printing powers of magnitude constants -- feat: `TagType` concept added +- feat: `SymbolicConstant` concept added - feat: `common_unit` selection algorithm improved to make `rev + rad` return `rad` - feat: litre text symbol changed from `l` to `L` to avoid ambiguity with `1` - feat: alternative litre unit symbol `L` added to prevent ambiguities with `1` @@ -23,13 +23,17 @@ - feat: `DerivedDimensionExpr`, `DerivedQuantitySpecExpr` and `DerivedUnitExpr` removed - feat: `MagnitudeSpecExpr` and `PowerVBase` removed and some functions renamed to limit possible ambiguity in overload resolution - feat: `std::is_object` constraint applied to `value_type_t` +- feat: `quantity_values` are now defined on top of `std::chrono::duration_values` +- feat: from now on truncation is not allowed in compound assignment - feat(example): currency example now uses `chrono::time_point` and has better interfaces - feat(example): `treat_as_floating_point` specializations for examples' types removed - (!) refactor: all `iec` quantity specifications are now deprecated and moved to `isq` - (!) refactor: `mag_constant` now takes a symbol and a value and the class deriving from it must be final - (!) refactor: `op==(U1, U2)` now checks for the same type (old behavior available as `equivalent(U1, U2)`) + `convertible` now verifies associated `quantity_spec` as well - (!) refactor: `ascii` -> `portable`, `unicode` -> `utf8`, 'A' -> 'P' -- (!) refactor: :boom: `char_traits` removed from `fixed_string` +- (!) refactor: `char_traits` removed from `fixed_string` +- (!) refactor: convertibility traits and concepts refactored to use `bool` flags instead of wrappers +- (!) refactor: tag types should not expose their members - refactor: `convertible(U1, U2)` implementation simplified - refactor: `abs` moved to `constexpr_math.h` - refactor: `unit_symbol_impl` simplified @@ -45,6 +49,13 @@ - refactor: `treat_as_floating_point` simplified and extended to use `std::chrono::treat_as_floating_point_v` - refactor: `wrapped_type_t` reuses `std::indirectly_readable_traits` - refactor: `expr_fractions` takes direct `OneType` type now instead of a trait +- refactor: Unicode symbols description reworked based on the latest SG16 recommendations +- refactor: `Mutable` concept applied to `quantity` and `quantity_point` +- refactor: `explicit` cleanup for deduction guides of `quantity` and `quantity_point` +- refactor: `point_origin_interface::op-` cleanup +- refactor: `QuantityLikeImpl` refactored to conform to API Reference by @JohelEGP +- refactor: `get_complexity` refactored to be 0-based and not account for a number of arguments in a list +- refactor: `get_complexity` refactored to returned maximum complexity of an element (instead of the sum of elements) - refactor(test): `derived_quantity` refactored to `child_quantity` - fix: missing `are_ingredients_convertible` overloads added - fix: constraints for magnitude added for `scaled_unit` and fixed `common_unit` instantiating it incorrectly @@ -56,6 +67,9 @@ - fix: `operator*(M, U u)` fixed for `U` being `scaled_unit` - fix: subsumption of `QuantityKindSpec` fixed - fix: `ValuePreservingTo` fixed to apply `std::remove_cvref_t` on `FromRep` +- fix: compound assignment operations on quantities now behave the same as on the underlying representation types +- fix: `QuantityConvertibleTo` used in `quantity_point` compound assignment +- fix: `convertible_kinds` implementation fixed - fix(tests): freestanding build fixed - test: unit tests for the inverse of `mag_constant` added - test: Unicode symbols used in unit tests @@ -63,18 +77,21 @@ - test: commutativity tests added to ISQ - test: one `kind_of` test added to reference tests - test: `pow<0>` and `pow<1>` tests added for dimensions +- test: more `get_common_quantity_spec` tests added - build: setting of some test_package CMake options enabled only for a `cxx_modules` build - ci: `sudo apt update` added for documentation.yml in hope that it will resolve missing system packages issue - ci: MSVC added to the CI +- ci: the latest not-released docs will use "HEAD" as a version from now on - docs: missing systems added to the "Project Structure" chapter - docs: graphs of ISQ kind hierarchies improved - docs: category of the ISO meeting reports changed to "WG21 Updates" - docs: blog comments support added -- docs: articles of the ISQ series added +- docs: Part 1-5 articles of the ISQ series added - docs: "Symbols of scaled units" chapter added + minor updates to scaled and common units chapters - docs: conan profile updated to present gcc-14 instead of gcc-12 which is no longer supported - docs: "Why derived units order is not preserved from the multiplication?" chapter added to FAQ - docs: "Many shades of the same unit" extended with a note about the derived units order +- docs: API Reference now presents _index.html_ instead of _full.hml_ ### 2.3.0 September 27, 2024 { id="2.3.0" } From 57a030a60265dc90fbd754ec227619cf8d10da94 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 5 Nov 2024 17:30:38 +0100 Subject: [PATCH 06/15] docs: 2.4.0 release --- CHANGELOG.md | 2 +- CITATION.cff | 8 ++++---- docs/getting_started/installation_and_usage.md | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61e5ac46e..8b4d9507c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## mp-units -### 2.4.0 WIP { id="2.4.0" } +### 2.4.0 November 5, 2024 { id="2.4.0" } - (!) feat: `phase_velocity` and `group_velocity` aliases removed from ISQ by ISO - feat: `iec::bit` using-declared in `iec::unit_symbols` diff --git a/CITATION.cff b/CITATION.cff index 6df0310c5..b5fb34e24 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -40,9 +40,9 @@ repository-code: "https://github.com/mpusz/mp-units" url: "https://mpusz.github.io/mp-units" repository-artifact: "https://conan.io/center/mp-units" -version: 2.3.0 -date-released: "2024-09-27" +version: 2.4.0 +date-released: "2024-11-05" identifiers: - - description: "The GitHub release URL of tag 2.3.0" + - description: "The GitHub release URL of tag 2.4.0" type: url - value: "https://github.com/mpusz/mp-units/releases/tag/v2.3.0" + value: "https://github.com/mpusz/mp-units/releases/tag/v2.4.0" diff --git a/docs/getting_started/installation_and_usage.md b/docs/getting_started/installation_and_usage.md index 7f56608f6..79de4a58c 100644 --- a/docs/getting_started/installation_and_usage.md +++ b/docs/getting_started/installation_and_usage.md @@ -265,7 +265,7 @@ The following steps may be performed to obtain an official library release: ```ini title="conanfile.txt" [requires] - mp-units/2.3.0 + mp-units/2.4.0 [options] @@ -323,7 +323,7 @@ with the following differences: ```ini title="conanfile.txt" hl_lines="2" [requires] - mp-units/2.4.0@mpusz/testing + mp-units/2.5.0@mpusz/testing [options] From 4ac237e69948619ae3d2c7eeb622c10990b3c936 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 5 Nov 2024 17:54:29 +0100 Subject: [PATCH 07/15] ci: documentation action should run on a new tag as well --- .github/workflows/documentation.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 2186fd168..b1bb541da 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -27,6 +27,10 @@ on: branches: - master - main + label: + types: + - created + - edited permissions: contents: write jobs: From c4b5e468e72594215a56498f8d633058319e11b5 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 5 Nov 2024 18:02:32 +0100 Subject: [PATCH 08/15] ci: building docs on new git tag fixed --- .github/workflows/documentation.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index b1bb541da..c82b7ed78 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -27,10 +27,8 @@ on: branches: - master - main - label: - types: - - created - - edited + tags: + - v* permissions: contents: write jobs: From ded2bf4db498d5599010ea52be98b33eefc69133 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 5 Nov 2024 18:24:14 +0100 Subject: [PATCH 09/15] ci: non-documenation actions should not run on tags --- .github/workflows/ci-clang-tidy.yml | 4 ++++ .github/workflows/ci-conan.yml | 4 ++++ .github/workflows/ci-freestanding.yml | 4 ++++ .github/workflows/ci-test-package-cmake.yml | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/.github/workflows/ci-clang-tidy.yml b/.github/workflows/ci-clang-tidy.yml index a91473568..015d42296 100644 --- a/.github/workflows/ci-clang-tidy.yml +++ b/.github/workflows/ci-clang-tidy.yml @@ -24,9 +24,13 @@ name: clang-tidy CI on: push: + branches: + - '**' paths-ignore: - "docs/**" pull_request: + branches: + - '**' paths-ignore: - "docs/**" diff --git a/.github/workflows/ci-conan.yml b/.github/workflows/ci-conan.yml index 8d5fc75a4..348ac4e1a 100644 --- a/.github/workflows/ci-conan.yml +++ b/.github/workflows/ci-conan.yml @@ -24,9 +24,13 @@ name: Conan CI on: push: + branches: + - '**' paths-ignore: - "docs/**" pull_request: + branches: + - '**' paths-ignore: - "docs/**" diff --git a/.github/workflows/ci-freestanding.yml b/.github/workflows/ci-freestanding.yml index 0b6918bfd..cde058db6 100644 --- a/.github/workflows/ci-freestanding.yml +++ b/.github/workflows/ci-freestanding.yml @@ -24,9 +24,13 @@ name: Freestanding CI on: push: + branches: + - '**' paths-ignore: - "docs/**" pull_request: + branches: + - '**' paths-ignore: - "docs/**" diff --git a/.github/workflows/ci-test-package-cmake.yml b/.github/workflows/ci-test-package-cmake.yml index 819bdc68f..d5bf5df0a 100644 --- a/.github/workflows/ci-test-package-cmake.yml +++ b/.github/workflows/ci-test-package-cmake.yml @@ -24,11 +24,15 @@ name: CMake Test Package CI on: push: + branches: + - '**' paths-ignore: - "docs/**" - "example/**" - "test/**" pull_request: + branches: + - '**' paths-ignore: - "docs/**" - "example/**" From f7dd05e9895404aa4fd747c45ca2f34fb6f82aff Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 5 Nov 2024 18:25:11 +0100 Subject: [PATCH 10/15] ci: documentation action limited only to commits that change documentation files --- .github/workflows/documentation.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index c82b7ed78..3072cd796 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -29,6 +29,11 @@ on: - main tags: - v* + paths: + - "docs/**" + - "CHANGELOG.md" + - "CONTRIBUTING.md" + - "mkdocs.yml" permissions: contents: write jobs: From 6e06eddf205deaf6c2f2f63500c8c70ec220a99f Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 5 Nov 2024 18:31:55 +0100 Subject: [PATCH 11/15] docs: CHANGELOG updated --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b4d9507c..3f5b82794 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -82,6 +82,9 @@ - ci: `sudo apt update` added for documentation.yml in hope that it will resolve missing system packages issue - ci: MSVC added to the CI - ci: the latest not-released docs will use "HEAD" as a version from now on +- ci: documentation action should run on a new tag as well +- ci: documentation action limited only to commits that change documentation files +- ci: non-documentation actions should not run on tags - docs: missing systems added to the "Project Structure" chapter - docs: graphs of ISQ kind hierarchies improved - docs: category of the ISO meeting reports changed to "WG21 Updates" From 1595fca9a995ac626a2dff01a710f3555c815618 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 5 Nov 2024 18:37:06 +0100 Subject: [PATCH 12/15] build: version bumped to 2.5.0 --- CHANGELOG.md | 2 ++ README.md | 2 +- src/CMakeLists.txt | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f5b82794..0c7b74fd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## mp-units +### 2.5.0 WIP { id="2.5.0" } + ### 2.4.0 November 5, 2024 { id="2.4.0" } - (!) feat: `phase_velocity` and `group_velocity` aliases removed from ISQ by ISO diff --git a/README.md b/README.md index 43511b870..8f4f7f404 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ [![GitHub Workflow Documentation](https://img.shields.io/github/actions/workflow/status/mpusz/mp-units/documentation.yml?branch=master&label=Documentation)](https://github.com/mpusz/mp-units/actions?query=workflow%3ADocumentation+branch%3Amaster) [![Conan stable](https://img.shields.io/conan/v/mp-units?label=ConanCenter&color=blue)](https://conan.io/center/mp-units) -[![Conan testing](https://img.shields.io/badge/mpusz.jfrog.io-2.4.0%3Atesting-blue)](https://mpusz.jfrog.io/ui/packages/conan:%2F%2Fmp-units/2.4.0) +[![Conan testing](https://img.shields.io/badge/mpusz.jfrog.io-2.5.0%3Atesting-blue)](https://mpusz.jfrog.io/ui/packages/conan:%2F%2Fmp-units/2.5.0) # `mp-units` - The quantities and units library for C++ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f698ac535..8b19f595b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,7 +21,7 @@ # SOFTWARE. cmake_minimum_required(VERSION 3.25) -project(mp-units VERSION 2.4.0 LANGUAGES CXX) +project(mp-units VERSION 2.5.0 LANGUAGES CXX) set(projectPrefix MP_UNITS_) From c7303cc5fb32a94bf0e3adb5e7257491e46a7ef3 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 5 Nov 2024 19:09:16 +0100 Subject: [PATCH 13/15] refactor: representation concepts refactored + some quantities switched to complex --- .../framework/representation_concepts.h | 107 ++++++++++++++---- .../mp-units/systems/isq/electromagnetism.h | 6 +- test/static/concepts_test.cpp | 7 +- test/static/isq_test.cpp | 6 +- test/static/quantity_test.cpp | 11 +- 5 files changed, 107 insertions(+), 30 deletions(-) diff --git a/src/core/include/mp-units/framework/representation_concepts.h b/src/core/include/mp-units/framework/representation_concepts.h index 3a19398ed..d802163d7 100644 --- a/src/core/include/mp-units/framework/representation_concepts.h +++ b/src/core/include/mp-units/framework/representation_concepts.h @@ -63,37 +63,106 @@ MP_UNITS_EXPORT enum class quantity_character : std::int8_t { scalar, complex, v namespace detail { -template -concept CommonTypeWith = - std::same_as, std::common_type_t> && - std::constructible_from, T> && std::constructible_from, U>; +template +concept WeaklyRegular = std::copyable && std::equality_comparable; -template -concept ScalableNumber = - std::regular_invocable, T, U> && std::regular_invocable, T, U>; +template +concept Scalar = is_scalar; template -concept CastableNumber = CommonTypeWith && ScalableNumber>; +concept Complex = is_complex; -// TODO Fix it according to sudo_cast implementation template -concept Scalable = - CastableNumber || (requires { typename wrapped_type_t; } && CastableNumber> && - ScalableNumber, std::intmax_t>>); +concept Vector = is_vector; template -concept WeaklyRegular = std::copyable && std::equality_comparable; +concept Tensor = is_tensor; + +template +concept IsOfCharacter = + (Ch == quantity_character::scalar && is_scalar) || (Ch == quantity_character::complex && is_complex) || + (Ch == quantity_character::vector && is_vector) || (Ch == quantity_character::tensor && is_tensor); +; + +template +using scaling_factor_type_t = conditional, long double, std::intmax_t>; + +template +concept ScalarRepresentation = Scalar && WeaklyRegular && requires(T a, T b, scaling_factor_type_t f) { + // scaling + { a* f } -> Scalar; + { f* a } -> Scalar; + { a / f } -> Scalar; + + // scalar operations + { a + b } -> Scalar; + { a - b } -> Scalar; + { a* b } -> Scalar; + { a / b } -> Scalar; +}; + +template +concept ComplexRepresentation = Complex && WeaklyRegular && requires(T a, T b, scaling_factor_type_t f) { + // scaling + // TODO The below conversion to `T` is an exception compared to other representation types + // `std::complex` * `U` do not work, but `std::complex` is convertible from `U` + // Maybe expose this as a customization point? + { a* T(f) } -> Complex; + { T(f) * a } -> Complex; + { a / T(f) } -> Complex; + + // complex operations + { a + b } -> Complex; + { a - b } -> Complex; + { a* b } -> Complex; + { a / b } -> Complex; + // TBD + // { re(a) } -> Scalar; + // { im(a) } -> Scalar; + // { mod(a) } -> Scalar; + // { arg(a) } -> Scalar; + // { conj(a) } -> Complex; +}; + +// TODO how to check for a complex(Scalar, Scalar) -> Complex? + +template +concept VectorRepresentation = Vector && WeaklyRegular && requires(T a, T b, scaling_factor_type_t f) { + // scaling + { a* f } -> Vector; + { f* a } -> Vector; + { a / f } -> Vector; + + // vector operations + { a + b } -> Vector; + { a - b } -> Vector; + // TBD + // { norm(a) } -> Scalar; + // { zero_vector() } -> Vector; + // { unit_vector(a) } -> Vector; + // { scalar_product(a, b) } -> Scalar; + // { vector_product(a, b) } -> Vector; + // { tensor_product(a, b) } -> Tensor2; + // divergence(a) + // rotation(a) +}; + +template +concept TensorRepresentation = Tensor && WeaklyRegular; // && requires(T a, T b) { + // TBD + // tensor operations + // { tensor_product(a, b) } -> Tensor4; + // { inner_product(a, b) } -> Tensor2; + // { scalar_product(a, b) } -> Scalar; +//}; } // namespace detail MP_UNITS_EXPORT template -concept Representation = - (is_scalar || is_complex || is_vector || is_tensor) && detail::WeaklyRegular && detail::Scalable; +concept Representation = detail::ScalarRepresentation || detail::ComplexRepresentation || + detail::VectorRepresentation || detail::TensorRepresentation; MP_UNITS_EXPORT template -concept RepresentationOf = - Representation && - ((Ch == quantity_character::scalar && is_scalar) || (Ch == quantity_character::complex && is_complex) || - (Ch == quantity_character::vector && is_vector) || (Ch == quantity_character::tensor && is_tensor)); +concept RepresentationOf = detail::IsOfCharacter && Representation; } // namespace mp_units diff --git a/src/systems/include/mp-units/systems/isq/electromagnetism.h b/src/systems/include/mp-units/systems/isq/electromagnetism.h index 96adc09fa..43988465b 100644 --- a/src/systems/include/mp-units/systems/isq/electromagnetism.h +++ b/src/systems/include/mp-units/systems/isq/electromagnetism.h @@ -122,8 +122,8 @@ inline constexpr auto instantaneous_power = electromagnetism_power; QUANTITY_SPEC(resistance, voltage / electric_current); QUANTITY_SPEC(conductance, inverse(resistance)); QUANTITY_SPEC(phase_difference, phase_angle); -QUANTITY_SPEC(electric_current_phasor, electric_current); -QUANTITY_SPEC(voltage_phasor, voltage); +QUANTITY_SPEC(electric_current_phasor, electric_current, quantity_character::complex); +QUANTITY_SPEC(voltage_phasor, voltage, quantity_character::complex); QUANTITY_SPEC(impedance, voltage_phasor / electric_current_phasor); inline constexpr auto complex_impedance = impedance; QUANTITY_SPEC(resistance_to_alternating_current, impedance); @@ -139,7 +139,7 @@ QUANTITY_SPEC(loss_factor, dimensionless, inverse(quality_factor)); QUANTITY_SPEC(loss_angle, angular_measure); QUANTITY_SPEC(active_power, isq::power, inverse(period) * (instantaneous_power * time)); QUANTITY_SPEC(complex_power, voltage_phasor* electric_current_phasor); // separate kind -QUANTITY_SPEC(apparent_power, complex_power); +QUANTITY_SPEC(apparent_power, complex_power, quantity_character::scalar); QUANTITY_SPEC(power_factor, dimensionless, active_power / apparent_power); QUANTITY_SPEC(reactive_power, isq::mass* pow<2>(isq::length) / pow<3>(isq::time)); // separate kind QUANTITY_SPEC(non_active_power, pow<1, 2>(pow<2>(apparent_power))); // separate kind diff --git a/test/static/concepts_test.cpp b/test/static/concepts_test.cpp index d43978287..c79e8851e 100644 --- a/test/static/concepts_test.cpp +++ b/test/static/concepts_test.cpp @@ -37,9 +37,10 @@ import std; #if MP_UNITS_HOSTED template -constexpr bool mp_units::is_scalar> = true; +constexpr bool mp_units::is_complex> = true; #endif + namespace { using namespace mp_units; @@ -268,7 +269,9 @@ static_assert(Representation); static_assert(!Representation); static_assert(!Representation>); #if MP_UNITS_HOSTED +static_assert(Representation>); static_assert(Representation>); +static_assert(Representation>); static_assert(!Representation); static_assert(!Representation); #endif @@ -279,7 +282,7 @@ static_assert(RepresentationOf); static_assert(!RepresentationOf); static_assert(!RepresentationOf, quantity_character::scalar>); #if MP_UNITS_HOSTED -static_assert(RepresentationOf, quantity_character::scalar>); +static_assert(RepresentationOf, quantity_character::complex>); static_assert(!RepresentationOf); static_assert(!RepresentationOf); #endif diff --git a/test/static/isq_test.cpp b/test/static/isq_test.cpp index 6f0e7b179..7d7fef844 100644 --- a/test/static/isq_test.cpp +++ b/test/static/isq_test.cpp @@ -303,8 +303,8 @@ static_assert(verify(isq::instantaneous_power, scalar, W)); static_assert(verify(isq::resistance, scalar, Ω)); static_assert(verify(isq::conductance, scalar, S)); static_assert(verify(isq::phase_difference, scalar, rad)); -static_assert(verify(isq::electric_current_phasor, scalar, A)); -static_assert(verify(isq::voltage_phasor, scalar, V)); +static_assert(verify(isq::electric_current_phasor, complex, A)); +static_assert(verify(isq::voltage_phasor, complex, V)); static_assert(verify(isq::impedance, scalar, Ω)); static_assert(verify(isq::complex_impedance, scalar, Ω)); static_assert(verify(isq::resistance_to_alternating_current, scalar, Ω)); @@ -321,7 +321,7 @@ static_assert(verify(isq::loss_angle, scalar, rad)); static_assert(verify(isq::active_power, scalar, W)); static_assert(verify(isq::apparent_power, scalar, V* A)); static_assert(verify(isq::power_factor, scalar, one)); -static_assert(verify(isq::complex_power, scalar, V* A)); +static_assert(verify(isq::complex_power, complex, V* A)); static_assert(verify(isq::reactive_power, scalar, V* A)); static_assert(verify(isq::non_active_power, scalar, V* A)); static_assert(verify(isq::active_energy, scalar, J, W* h)); diff --git a/test/static/quantity_test.cpp b/test/static/quantity_test.cpp index e175f25c7..276a70e7c 100644 --- a/test/static/quantity_test.cpp +++ b/test/static/quantity_test.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -46,7 +47,7 @@ import std; #if MP_UNITS_HOSTED template -constexpr bool mp_units::is_scalar> = true; +constexpr bool mp_units::is_complex> = true; #endif template<> @@ -282,8 +283,12 @@ static_assert((1. * rad + 1. * deg).in(deg) != 0 * deg); #if MP_UNITS_HOSTED using namespace std::complex_literals; -static_assert(((2. + 1i) * V).in(mV).numerical_value_in(mV) == 2000. + 1000i); -static_assert(((2. + 1i) * V).in(mV).numerical_value_in(V) == 2. + 1i); +static_assert(((2.f + 1if) * isq::voltage_phasor[V]).in(mV).numerical_value_in(mV) == 2000.f + 1000if); +static_assert(((2.f + 1if) * isq::voltage_phasor[V]).in(mV).numerical_value_in(V) == 2.f + 1if); +static_assert(((2. + 1i) * isq::voltage_phasor[V]).in(mV).numerical_value_in(mV) == 2000. + 1000i); +static_assert(((2. + 1i) * isq::voltage_phasor[V]).in(mV).numerical_value_in(V) == 2. + 1i); +static_assert(((2.L + 1il) * isq::voltage_phasor[V]).in(mV).numerical_value_in(mV) == 2000.L + 1000il); +static_assert(((2.L + 1il) * isq::voltage_phasor[V]).in(mV).numerical_value_in(V) == 2.L + 1il); #endif template typename Q> From c2c02dff59c8dbdf9555336caa78a2cd18f99e60 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 5 Nov 2024 19:38:53 +0100 Subject: [PATCH 14/15] ci: Conan CI restored for tags to properly promote a package to the Artifactory --- .github/workflows/ci-conan.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/ci-conan.yml b/.github/workflows/ci-conan.yml index 348ac4e1a..8d5fc75a4 100644 --- a/.github/workflows/ci-conan.yml +++ b/.github/workflows/ci-conan.yml @@ -24,13 +24,9 @@ name: Conan CI on: push: - branches: - - '**' paths-ignore: - "docs/**" pull_request: - branches: - - '**' paths-ignore: - "docs/**" From 4e6abda7276985cc5c2d6cf0d95e9c29ce04a49e Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 5 Nov 2024 19:46:13 +0100 Subject: [PATCH 15/15] docs: 2.4.0 release announcement published --- docs/blog/posts/2.4.0-released.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/blog/posts/2.4.0-released.md b/docs/blog/posts/2.4.0-released.md index 714379b48..2e33210c5 100644 --- a/docs/blog/posts/2.4.0-released.md +++ b/docs/blog/posts/2.4.0-released.md @@ -1,5 +1,4 @@ --- -draft: true date: 2024-11-05 authors: - mpusz