From c69bd140b201f92d46407a7237416923a909734e Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 6 Jun 2024 13:18:45 +0200 Subject: [PATCH] refactor: all units made `final` --- .../framework_basics/design_overview.md | 12 +-- .../dimensionless_quantities.md | 14 +-- .../faster_than_lightspeed_constants.md | 4 +- .../interface_introduction.md | 10 +- .../framework_basics/systems_of_units.md | 20 ++-- .../framework_basics/text_output.md | 36 +++---- .../framework_basics/the_affine_space.md | 6 +- .../framework_basics/value_conversions.md | 12 +-- example/currency.cpp | 8 +- .../mp-units/framework/system_reference.h | 8 +- src/core/include/mp-units/framework/unit.h | 24 ++--- .../include/mp-units/systems/angular/units.h | 10 +- src/systems/include/mp-units/systems/cgs.h | 14 +-- src/systems/include/mp-units/systems/hep.h | 8 +- src/systems/include/mp-units/systems/iau.h | 26 ++--- .../systems/iec80000/binary_prefixes.h | 16 +-- .../include/mp-units/systems/iec80000/units.h | 10 +- .../include/mp-units/systems/imperial.h | 42 ++++---- .../include/mp-units/systems/international.h | 38 +++---- .../include/mp-units/systems/natural.h | 2 +- .../include/mp-units/systems/si/constants.h | 18 ++-- .../include/mp-units/systems/si/prefixes.h | 48 ++++----- .../include/mp-units/systems/si/units.h | 82 ++++++++-------- .../include/mp-units/systems/typographic.h | 8 +- src/systems/include/mp-units/systems/usc.h | 92 ++++++++--------- test/runtime/truncation_test.cpp | 2 +- test/static/dimension_test.cpp | 2 +- test/static/quantity_point_test.cpp | 2 +- test/static/quantity_spec_test.cpp | 2 +- test/static/reference_test.cpp | 34 +++---- test/static/unit_test.cpp | 98 ++++++++++--------- 31 files changed, 357 insertions(+), 351 deletions(-) diff --git a/docs/users_guide/framework_basics/design_overview.md b/docs/users_guide/framework_basics/design_overview.md index da38cd95..8513ee80 100644 --- a/docs/users_guide/framework_basics/design_overview.md +++ b/docs/users_guide/framework_basics/design_overview.md @@ -234,13 +234,13 @@ A unit can be defined by the user in one of the following ways: template struct kilo_ : prefixed_unit<"k", mag_power<10, 3>, U{}> {}; template inline constexpr kilo_ kilo; -inline constexpr struct second : named_unit<"s", kind_of> {} second; -inline constexpr struct minute : named_unit<"min", mag<60> * second> {} minute; -inline constexpr struct gram : named_unit<"g", kind_of> {} gram; -inline constexpr struct kilogram : decltype(kilo) {} kilogram; -inline constexpr struct newton : named_unit<"N", kilogram * metre / square(second)> {} newton; +inline constexpr struct second final : named_unit<"s", kind_of> {} second; +inline constexpr struct minute final : named_unit<"min", mag<60> * second> {} minute; +inline constexpr struct gram final : named_unit<"g", kind_of> {} gram; +inline constexpr auto kilogram = kilo; +inline constexpr struct newton final : named_unit<"N", kilogram * metre / square(second)> {} newton; -inline constexpr struct speed_of_light_in_vacuum : named_unit<"c", mag<299'792'458> * metre / second> {} speed_of_light_in_vacuum; +inline constexpr struct speed_of_light_in_vacuum final : named_unit<"c", mag<299'792'458> * metre / second> {} speed_of_light_in_vacuum; ``` The [unit equation](../../appendix/glossary.md#unit-equation) of `si::metre / si::second` results diff --git a/docs/users_guide/framework_basics/dimensionless_quantities.md b/docs/users_guide/framework_basics/dimensionless_quantities.md index 3019828f..05bbca18 100644 --- a/docs/users_guide/framework_basics/dimensionless_quantities.md +++ b/docs/users_guide/framework_basics/dimensionless_quantities.md @@ -113,7 +113,7 @@ that uses a unit that is proportional to the ratio of kilometers per megaparsecs units of _length_: ```cpp -inline constexpr struct hubble_constant : +inline constexpr struct hubble_constant final : named_unit<{u8"H₀", "H_0"}, mag_ratio<701, 10> * si::kilo / si::second / si::mega> {} hubble_constant; ``` @@ -158,9 +158,9 @@ Besides the unit `one`, there are a few other scaled units predefined in the lib with dimensionless quantities: ```cpp -inline constexpr struct percent : named_unit<"%", mag_ratio<1, 100> * one> {} percent; -inline constexpr struct per_mille : named_unit<{u8"‰", "%o"}, mag_ratio<1, 1000> * one> {} per_mille; -inline constexpr struct parts_per_million : named_unit<"ppm", mag_ratio<1, 1'000'000> * one> {} parts_per_million; +inline constexpr struct percent final : named_unit<"%", mag_ratio<1, 100> * one> {} percent; +inline constexpr struct per_mille final : named_unit<{u8"‰", "%o"}, mag_ratio<1, 1000> * one> {} per_mille; +inline constexpr struct parts_per_million final : named_unit<"ppm", mag_ratio<1, 1'000'000> * one> {} parts_per_million; inline constexpr auto ppm = parts_per_million; ``` @@ -242,9 +242,9 @@ With the above, we can constrain `radian`, `steradian`, and `bit` to be allowed specific quantity kinds only: ```cpp -inline constexpr struct radian : named_unit<"rad", metre / metre, kind_of> {} radian; -inline constexpr struct steradian : named_unit<"sr", square(metre) / square(metre), kind_of> {} steradian; -inline constexpr struct bit : named_unit<"bit", one, kind_of> {} bit; +inline constexpr struct radian final : named_unit<"rad", metre / metre, kind_of> {} radian; +inline constexpr struct steradian final : named_unit<"sr", square(metre) / square(metre), kind_of> {} steradian; +inline constexpr struct bit final : named_unit<"bit", one, kind_of> {} bit; ``` but still allow the usage of `one` and its scaled versions for such quantities. diff --git a/docs/users_guide/framework_basics/faster_than_lightspeed_constants.md b/docs/users_guide/framework_basics/faster_than_lightspeed_constants.md index d69ef39c..cef490db 100644 --- a/docs/users_guide/framework_basics/faster_than_lightspeed_constants.md +++ b/docs/users_guide/framework_basics/faster_than_lightspeed_constants.md @@ -39,12 +39,12 @@ namespace si { namespace si2019 { -inline constexpr struct speed_of_light_in_vacuum : +inline constexpr struct speed_of_light_in_vacuum final : named_unit<"c", mag<299'792'458> * metre / second> {} speed_of_light_in_vacuum; } // namespace si2019 -inline constexpr struct magnetic_constant : +inline constexpr struct magnetic_constant final : named_unit<{u8"μ₀", "u_0"}, mag<4> * mag_pi * mag_power<10, -7> * henry / metre> {} magnetic_constant; } // namespace mp_units::si diff --git a/docs/users_guide/framework_basics/interface_introduction.md b/docs/users_guide/framework_basics/interface_introduction.md index f1bcc16f..9f3de85c 100644 --- a/docs/users_guide/framework_basics/interface_introduction.md +++ b/docs/users_guide/framework_basics/interface_introduction.md @@ -6,8 +6,8 @@ The **mp-units** library decided to use a rather unusual pattern to define entit Here is how we define `metre` and `second` [SI](../../appendix/glossary.md#si) base units: ```cpp -inline constexpr struct metre : named_unit<"m", kind_of> {} metre; -inline constexpr struct second : named_unit<"s", kind_of> {} second; +inline constexpr struct metre final : named_unit<"m", kind_of> {} metre; +inline constexpr struct second final : named_unit<"s", kind_of> {} second; ``` Please note that the above reuses the same identifier for a type and its value. The rationale @@ -94,9 +94,9 @@ the value-based [unit equation](../../appendix/glossary.md#unit-equation) to a c definition: ```cpp -inline constexpr struct newton : named_unit<"N", kilogram * metre / square(second)> {} newton; -inline constexpr struct pascal : named_unit<"Pa", newton / square(metre)> {} pascal; -inline constexpr struct joule : named_unit<"J", newton * metre> {} joule; +inline constexpr struct newton final : named_unit<"N", kilogram * metre / square(second)> {} newton; +inline constexpr struct pascal final : named_unit<"Pa", newton / square(metre)> {} pascal; +inline constexpr struct joule final : named_unit<"J", newton * metre> {} joule; ``` diff --git a/docs/users_guide/framework_basics/systems_of_units.md b/docs/users_guide/framework_basics/systems_of_units.md index 3d263c11..df37b6bf 100644 --- a/docs/users_guide/framework_basics/systems_of_units.md +++ b/docs/users_guide/framework_basics/systems_of_units.md @@ -26,7 +26,7 @@ this is expressed by associating a quantity kind (that we discussed in detail in previous chapter) with a unit that is used to express it: ```cpp -inline constexpr struct metre : named_unit<"m", kind_of> {} metre; +inline constexpr struct metre final : named_unit<"m", kind_of> {} metre; ``` !!! important @@ -67,7 +67,7 @@ of a specific predefined [unit equation](../../appendix/glossary.md#unit-equatio For example, a unit of _power_ quantity is defined in the library as: ```cpp -inline constexpr struct watt : named_unit<"W", joule / second> {} watt; +inline constexpr struct watt final : named_unit<"W", joule / second> {} watt; ``` However, a _power_ quantity can be expressed in other units as well. For example, @@ -110,8 +110,8 @@ The library allows constraining such units to work only with quantities of a spe the following way: ```cpp -inline constexpr struct hertz : named_unit<"Hz", one / second, kind_of> {} hertz; -inline constexpr struct becquerel : named_unit<"Bq", one / second, kind_of> {} becquerel; +inline constexpr struct hertz final : named_unit<"Hz", one / second, kind_of> {} hertz; +inline constexpr struct becquerel final : named_unit<"Bq", one / second, kind_of> {} becquerel; ``` With the above, `hertz` can only be used with _frequencies_, while `becquerel` should only be used with @@ -168,25 +168,25 @@ be explicitly expressed with predefined SI prefixes. Those include units like mi electronvolt: ```cpp -inline constexpr struct minute : named_unit<"min", mag<60> * si::second> {} minute; -inline constexpr struct hour : named_unit<"h", mag<60> * minute> {} hour; -inline constexpr struct electronvolt : named_unit<"eV", mag_ratio<1'602'176'634, 1'000'000'000> * mag_power<10, -19> * si::joule> {} electronvolt; +inline constexpr struct minute final : named_unit<"min", mag<60> * si::second> {} minute; +inline constexpr struct hour final : named_unit<"h", mag<60> * minute> {} hour; +inline constexpr struct electronvolt final : named_unit<"eV", mag_ratio<1'602'176'634, 1'000'000'000> * mag_power<10, -19> * si::joule> {} electronvolt; ``` Also, units of other [systems of units](../../appendix/glossary.md#system-of-units) are often defined in terms of scaled versions of the SI units. For example, the international yard is defined as: ```cpp -inline constexpr struct yard : named_unit<"yd", mag_ratio<9'144, 10'000> * si::metre> {} yard; +inline constexpr struct yard final : named_unit<"yd", mag_ratio<9'144, 10'000> * si::metre> {} yard; ``` For some units, a magnitude might also be irrational. The best example here is a `degree` which is defined using a floating-point magnitude having a factor of the number π (Pi): ```cpp -inline constexpr struct mag_pi : magnitude> {} mag_pi; +inline constexpr struct mag_pi final : magnitude> {} mag_pi; ``` ```cpp -inline constexpr struct degree : named_unit<{u8"°", "deg"}, mag_pi / mag<180> * si::radian> {} degree; +inline constexpr struct degree final : named_unit<{u8"°", "deg"}, mag_pi / mag<180> * si::radian> {} degree; ``` diff --git a/docs/users_guide/framework_basics/text_output.md b/docs/users_guide/framework_basics/text_output.md index 67bd4395..6487640e 100644 --- a/docs/users_guide/framework_basics/text_output.md +++ b/docs/users_guide/framework_basics/text_output.md @@ -45,18 +45,18 @@ and units of derived quantities. === "Units" ```cpp - inline constexpr struct second : named_unit<"s", kind_of> {} second; - inline constexpr struct metre : named_unit<"m", kind_of> {} metre; - inline constexpr struct gram : named_unit<"g", kind_of> {} gram; + inline constexpr struct second final : named_unit<"s", kind_of> {} second; + inline constexpr struct metre final : named_unit<"m", kind_of> {} metre; + inline constexpr struct gram final : named_unit<"g", kind_of> {} gram; inline constexpr auto kilogram = kilo; - inline constexpr struct newton : named_unit<"N", kilogram * metre / square(second)> {} newton; - inline constexpr struct joule : named_unit<"J", newton * metre> {} joule; - inline constexpr struct watt : named_unit<"W", joule / second> {} watt; - inline constexpr struct coulomb : named_unit<"C", ampere * second> {} coulomb; - inline constexpr struct volt : named_unit<"V", watt / ampere> {} volt; - inline constexpr struct farad : named_unit<"F", coulomb / volt> {} farad; - inline constexpr struct ohm : named_unit<{u8"Ω", "ohm"}, volt / ampere> {} ohm; + inline constexpr struct newton final : named_unit<"N", kilogram * metre / square(second)> {} newton; + inline constexpr struct joule final : named_unit<"J", newton * metre> {} joule; + inline constexpr struct watt final : named_unit<"W", joule / second> {} watt; + inline constexpr struct coulomb final : named_unit<"C", ampere * second> {} coulomb; + inline constexpr struct volt final : named_unit<"V", watt / ampere> {} volt; + inline constexpr struct farad final : named_unit<"F", coulomb / volt> {} farad; + inline constexpr struct ohm final : named_unit<{u8"Ω", "ohm"}, volt / ampere> {} ohm; ``` === "Prefixes" @@ -75,13 +75,13 @@ and units of derived quantities. === "Constants" ```cpp - inline constexpr struct hyperfine_structure_transition_frequency_of_cs : named_unit<{u8"Δν_Cs", "dv_Cs"}, mag<9'192'631'770> * hertz> {} hyperfine_structure_transition_frequency_of_cs; - inline constexpr struct speed_of_light_in_vacuum : named_unit<"c", mag<299'792'458> * metre / second> {} speed_of_light_in_vacuum; - inline constexpr struct planck_constant : named_unit<"h", mag_ratio<662'607'015, 100'000'000> * mag_power<10, -34> * joule * second> {} planck_constant; - inline constexpr struct elementary_charge : named_unit<"e", mag_ratio<1'602'176'634, 1'000'000'000> * mag_power<10, -19> * coulomb> {} elementary_charge; - inline constexpr struct boltzmann_constant : named_unit<"k", mag_ratio<1'380'649, 1'000'000> * mag_power<10, -23> * joule / kelvin> {} boltzmann_constant; - inline constexpr struct avogadro_constant : named_unit<"N_A", mag_ratio<602'214'076, 100'000'000> * mag_power<10, 23> / mole> {} avogadro_constant; - inline constexpr struct luminous_efficacy : named_unit<"K_cd", mag<683> * lumen / watt> {} luminous_efficacy; + inline constexpr struct hyperfine_structure_transition_frequency_of_cs final : named_unit<{u8"Δν_Cs", "dv_Cs"}, mag<9'192'631'770> * hertz> {} hyperfine_structure_transition_frequency_of_cs; + inline constexpr struct speed_of_light_in_vacuum final : named_unit<"c", mag<299'792'458> * metre / second> {} speed_of_light_in_vacuum; + inline constexpr struct planck_constant final : named_unit<"h", mag_ratio<662'607'015, 100'000'000> * mag_power<10, -34> * joule * second> {} planck_constant; + inline constexpr struct elementary_charge final : named_unit<"e", mag_ratio<1'602'176'634, 1'000'000'000> * mag_power<10, -19> * coulomb> {} elementary_charge; + inline constexpr struct boltzmann_constant final : named_unit<"k", mag_ratio<1'380'649, 1'000'000> * mag_power<10, -23> * joule / kelvin> {} boltzmann_constant; + inline constexpr struct avogadro_constant final : named_unit<"N_A", mag_ratio<602'214'076, 100'000'000> * mag_power<10, 23> / mole> {} avogadro_constant; + inline constexpr struct luminous_efficacy final : named_unit<"K_cd", mag<683> * lumen / watt> {} luminous_efficacy; ``` !!! important @@ -105,7 +105,7 @@ and units of derived quantities. template name to initialize it with two symbols: ```cpp - inline constexpr struct ohm : named_unit {} ohm; + inline constexpr struct ohm final : named_unit {} ohm; ``` diff --git a/docs/users_guide/framework_basics/the_affine_space.md b/docs/users_guide/framework_basics/the_affine_space.md index c21bceea..5ed28660 100644 --- a/docs/users_guide/framework_basics/the_affine_space.md +++ b/docs/users_guide/framework_basics/the_affine_space.md @@ -426,16 +426,16 @@ definitions: ```cpp namespace si { -inline constexpr struct kelvin : +inline constexpr struct kelvin final : named_unit<"K", kind_of, zeroth_kelvin> {} kelvin; -inline constexpr struct degree_Celsius : +inline constexpr struct degree_Celsius final : named_unit<{u8"°C", "`C"}, kelvin, zeroth_degree_Celsius> {} degree_Celsius; } namespace usc { -inline constexpr struct degree_Fahrenheit : +inline constexpr struct degree_Fahrenheit final : named_unit<{u8"°F", "`F"}, mag_ratio<5, 9> * si::degree_Celsius, zeroth_degree_Fahrenheit> {} degree_Fahrenheit; diff --git a/docs/users_guide/framework_basics/value_conversions.md b/docs/users_guide/framework_basics/value_conversions.md index bed6e928..ecc6d6c9 100644 --- a/docs/users_guide/framework_basics/value_conversions.md +++ b/docs/users_guide/framework_basics/value_conversions.md @@ -88,8 +88,8 @@ the `value_cast(q)` which always returns the most precise result: inline constexpr struct dim_currency : base_dimension<"$"> {} dim_currency; inline constexpr struct currency : quantity_spec {} currency; - inline constexpr struct us_dollar : named_unit<"USD", kind_of> {} us_dollar; - inline constexpr struct scaled_us_dollar : named_unit<"USD_s", mag_power<10, -8> * us_dollar> {} scaled_us_dollar; + inline constexpr struct us_dollar final : named_unit<"USD", kind_of> {} us_dollar; + inline constexpr struct scaled_us_dollar final : named_unit<"USD_s", mag_power<10, -8> * us_dollar> {} scaled_us_dollar; namespace unit_symbols { @@ -108,8 +108,8 @@ the `value_cast(q)` which always returns the most precise result: inline constexpr struct dim_currency : base_dimension<"$"> {} dim_currency; inline constexpr struct currency : quantity_spec {} currency; - inline constexpr struct us_dollar : named_unit<"USD", kind_of> {} us_dollar; - inline constexpr struct scaled_us_dollar : named_unit<"USD_s", mag_power<10, -8> * us_dollar> {} scaled_us_dollar; + inline constexpr struct us_dollar final : named_unit<"USD", kind_of> {} us_dollar; + inline constexpr struct scaled_us_dollar final : named_unit<"USD_s", mag_power<10, -8> * us_dollar> {} scaled_us_dollar; namespace unit_symbols { @@ -128,8 +128,8 @@ the `value_cast(q)` which always returns the most precise result: inline constexpr struct dim_currency : base_dimension<"$"> {} dim_currency; QUANTITY_SPEC(currency, dim_currency); - inline constexpr struct us_dollar : named_unit<"USD", kind_of> {} us_dollar; - inline constexpr struct scaled_us_dollar : named_unit<"USD_s", mag_power<10, -8> * us_dollar> {} scaled_us_dollar; + inline constexpr struct us_dollar final : named_unit<"USD", kind_of> {} us_dollar; + inline constexpr struct scaled_us_dollar final : named_unit<"USD_s", mag_power<10, -8> * us_dollar> {} scaled_us_dollar; namespace unit_symbols { diff --git a/example/currency.cpp b/example/currency.cpp index a638fe86..bbbb55cf 100644 --- a/example/currency.cpp +++ b/example/currency.cpp @@ -40,10 +40,10 @@ inline constexpr struct dim_currency : base_dimension<"$"> {} dim_currency; QUANTITY_SPEC(currency, dim_currency); -inline constexpr struct euro : named_unit<"EUR", kind_of> {} euro; -inline constexpr struct us_dollar : named_unit<"USD", kind_of> {} us_dollar; -inline constexpr struct great_british_pound : named_unit<"GBP", kind_of> {} great_british_pound; -inline constexpr struct japanese_jen : named_unit<"JPY", kind_of> {} japanese_jen; +inline constexpr struct euro final : named_unit<"EUR", kind_of> {} euro; +inline constexpr struct us_dollar final : named_unit<"USD", kind_of> {} us_dollar; +inline constexpr struct great_british_pound final : named_unit<"GBP", kind_of> {} great_british_pound; +inline constexpr struct japanese_jen final : named_unit<"JPY", kind_of> {} japanese_jen; // clang-format on namespace unit_symbols { diff --git a/src/core/include/mp-units/framework/system_reference.h b/src/core/include/mp-units/framework/system_reference.h index b4c202ec..5718cb1a 100644 --- a/src/core/include/mp-units/framework/system_reference.h +++ b/src/core/include/mp-units/framework/system_reference.h @@ -45,10 +45,10 @@ namespace mp_units { * @code{.cpp} * // hypothetical natural system of units for c=1 * - * inline constexpr struct second : named_unit<"s"> {} second; - * inline constexpr struct minute : named_unit<"min", mag<60> * second> {} minute; - * inline constexpr struct gram : named_unit<"g"> {} gram; - * inline constexpr struct kilogram : decltype(si::kilo) {} kilogram; + * inline constexpr struct second final : named_unit<"s"> {} second; + * inline constexpr struct minute final : named_unit<"min", mag<60> * second> {} minute; + * inline constexpr struct gram final : named_unit<"g"> {} gram; + * inline constexpr auto kilogram = si::kilo; * * inline constexpr struct time : system_reference {} time; * inline constexpr struct length : system_reference {} length; diff --git a/src/core/include/mp-units/framework/unit.h b/src/core/include/mp-units/framework/unit.h index 7d5a7f07..5cc51d63 100644 --- a/src/core/include/mp-units/framework/unit.h +++ b/src/core/include/mp-units/framework/unit.h @@ -104,12 +104,12 @@ inline constexpr bool is_specialization_of_scaled_unit> = true * For example: * * @code{.cpp} - * inline constexpr struct second : named_unit<"s", time> {} second; - * inline constexpr struct metre : named_unit<"m", length> {} metre; - * inline constexpr struct hertz : named_unit<"Hz", inverse(second)> {} hertz; - * inline constexpr struct newton : named_unit<"N", kilogram * metre / square(second)> {} newton; - * inline constexpr struct degree_Celsius : named_unit<{u8"°C", "`C"}, kelvin> {} degree_Celsius; - * inline constexpr struct minute : named_unit<"min", mag<60> * second> {} minute; + * inline constexpr struct second final : named_unit<"s", kind_of