diff --git a/README.md b/README.md index c2c04f0a7..be9407222 100644 --- a/README.md +++ b/README.md @@ -63,10 +63,9 @@ static_assert(1 * h == 3600 * s); static_assert(1 * km + 1 * m == 1001 * m); // derived quantities -inline constexpr auto kmph = km / h; -static_assert(1 * km / (1 * s) == 1000 * (m / s)); -static_assert(2 * kmph * (2 * h) == 4 * km); -static_assert(2 * km / (2 * kmph) == 1 * h); +static_assert(1 * km / (1 * s) == 1000 * m / s); +static_assert(2 * km / h * (2 * h) == 4 * km); +static_assert(2 * km / (2 * km / h) == 1 * h); static_assert(2 * m * (3 * m) == 6 * m2); @@ -103,7 +102,7 @@ int main() using namespace mp_units::si::unit_symbols; using namespace mp_units::international::unit_symbols; - constexpr quantity v1 = 110 * (km / h); + constexpr quantity v1 = 110 * km / h; constexpr quantity v2 = 70 * mph; constexpr quantity v3 = avg_speed(220. * isq::distance[km], 2 * h); constexpr quantity v4 = avg_speed(isq::distance(140. * mi), 2 * h); diff --git a/docs/getting_started/code_example.md b/docs/getting_started/code_example.md index 857614f11..8f22524c6 100644 --- a/docs/getting_started/code_example.md +++ b/docs/getting_started/code_example.md @@ -16,10 +16,9 @@ static_assert(1 * h == 3600 * s); static_assert(1 * km + 1 * m == 1001 * m); // derived quantities -inline constexpr auto kmph = km / h; -static_assert(1 * km / (1 * s) == 1000 * (m / s)); -static_assert(2 * kmph * (2 * h) == 4 * km); -static_assert(2 * km / (2 * kmph) == 1 * h); +static_assert(1 * km / (1 * s) == 1000 * m / s); +static_assert(2 * km / h * (2 * h) == 4 * km); +static_assert(2 * km / (2 * km / h) == 1 * h); static_assert(2 * m * (3 * m) == 6 * m2); @@ -59,7 +58,7 @@ int main() using namespace mp_units::si::unit_symbols; using namespace mp_units::international::unit_symbols; - constexpr quantity v1 = 110 * (km / h); + constexpr quantity v1 = 110 * km / h; constexpr quantity v2 = 70 * mph; constexpr quantity v3 = avg_speed(220. * isq::distance[km], 2 * h); constexpr quantity v4 = avg_speed(isq::distance(140. * mi), 2 * h); diff --git a/docs/getting_started/faq.md b/docs/getting_started/faq.md index 1fef6904a..5bd1c0f0d 100644 --- a/docs/getting_started/faq.md +++ b/docs/getting_started/faq.md @@ -92,47 +92,6 @@ In the **mp-units** library, both a number and a unit have to always be explicit form a quantity. -## Why `60 * km / h` does not compile? - -The library design does not allow multiplying or dividing a quantity (the result of `60 * km`) -by another unit. This significantly limits the number of possible errors and surprises in the -quantity equations. - -Consider the following expression: - -```cpp -auto q = 60 * km / 2 * h; -``` - -Looks like `30 km/h`, right? But it is not. If the above code was allowed, it would result -in `30 km⋅h`. In case you want to divide `60 * km` by `2 * h` a parenthesis is needed: - -```cpp -auto q = 60 * km / (2 * h); -``` - -Another surprising issue could result from the following code: - -```cpp -template -auto make_length(T v) { return v * si::metre; } - -auto v = 42; -auto q = make_length(v); -``` - -The above might look like a good idea, but consider what would happen in the user provided -an already existing quantity: - -```cpp -auto v = 42 * m; -auto q = make_length(v); -``` - -Fortunately, with the current design, such issues are detected at compile-time as -multiplying or dividing a quantity by a unit is not be supported. - - ## Why a dimensionless quantity is not just a fundamental arithmetic type? In the initial design of this library, the resulting type of division of two quantities was their diff --git a/docs/getting_started/quick_start.md b/docs/getting_started/quick_start.md index cd34e6f93..bc4db9fb6 100644 --- a/docs/getting_started/quick_start.md +++ b/docs/getting_started/quick_start.md @@ -67,14 +67,9 @@ quantity q = make_quantity(42); Sometimes it might be awkward to type some derived units: ```cpp -quantity speed = 60 * (km / h); +quantity speed = 60 * km / h; ``` -!!! note - - Please note that `60 * km / h` will not compile. To read more about the rationale for such - a design please check our [FAQ](faq.md#why-dont-we-use-udls-to-create-a-quantity). - In case such a unit is used a lot in the project, a user can easily provide a nicely named wrapper for it with: diff --git a/docs/users_guide/framework_basics/character_of_a_quantity.md b/docs/users_guide/framework_basics/character_of_a_quantity.md index 990a89316..a9181f807 100644 --- a/docs/users_guide/framework_basics/character_of_a_quantity.md +++ b/docs/users_guide/framework_basics/character_of_a_quantity.md @@ -212,9 +212,9 @@ either: The following does not work: ```cpp - Quantity auto q1 = la_vector{1, 2, 3} * (m / s); - Quantity auto q2 = isq::velocity(la_vector{1, 2, 3} * (m / s)); - quantity q3{la_vector{1, 2, 3} * (m / s)}; + Quantity auto q1 = la_vector{1, 2, 3} * m / s; + Quantity auto q2 = isq::velocity(la_vector{1, 2, 3} * m / s); + quantity q3{la_vector{1, 2, 3} * m / s}; ``` In all the cases above, the SI unit `m / s` has an associated scalar quantity of `isq::length / isq::time`. diff --git a/docs/users_guide/framework_basics/interface_introduction.md b/docs/users_guide/framework_basics/interface_introduction.md index 017859e63..6776cd29a 100644 --- a/docs/users_guide/framework_basics/interface_introduction.md +++ b/docs/users_guide/framework_basics/interface_introduction.md @@ -152,20 +152,22 @@ identities used in the library: | `QuantitySpec` | `dimensionless` | | `Unit` | `one` | -In the equations, a user can refer to an identity object either explicitly: +In the equations, a user can explicitly refer to an identity object: ```cpp constexpr auto my_unit = one / second; ``` -or implicitly: +!!! note -```cpp -constexpr auto my_unit = 1 / second; -``` + Another way to achieve the same result is to call an `inverse()` function: + + ```cpp + constexpr auto my_unit = inverse(second); + ``` -Both cases with result in the same expression template being generated and put into the wrapper -class template. + Both cases will result in the same expression template being generated and put into the wrapper + class template. ### Supported operations and their results diff --git a/docs/users_guide/framework_basics/quantity_arithmetics.md b/docs/users_guide/framework_basics/quantity_arithmetics.md index 954720123..51ede8ea1 100644 --- a/docs/users_guide/framework_basics/quantity_arithmetics.md +++ b/docs/users_guide/framework_basics/quantity_arithmetics.md @@ -136,7 +136,7 @@ However, suppose we multiply or divide quantities of the same or different types number by a quantity. In that case, we most probably will end up in a quantity of yet another type: ```cpp -static_assert(120 * km / (2 * h) == 60 * (km / h)); +static_assert(120 * km / (2 * h) == 60 * km / h); static_assert(isq::width(2 * m) * isq::length(2 * m) == isq::area(4 * m2)); static_assert(50 / isq::time(1 * s) == isq::frequency(50 * Hz)); ``` @@ -283,7 +283,7 @@ every time when we want to ensure that we deal with a non-zero or positive value We could implement such checks in the following way: ```cpp -if (q1 / q2 != 0 * (m / s)) +if (q1 / q2 != 0 * m / s) // ... ``` diff --git a/docs/users_guide/framework_basics/systems_of_units.md b/docs/users_guide/framework_basics/systems_of_units.md index 50965fe1b..9607bd7d4 100644 --- a/docs/users_guide/framework_basics/systems_of_units.md +++ b/docs/users_guide/framework_basics/systems_of_units.md @@ -107,8 +107,8 @@ However, it also explicitly states: The library allows constraining such units in the following way: ```cpp -inline constexpr struct hertz : named_unit<"Hz", 1 / second, kind_of> {} hertz; -inline constexpr struct becquerel : named_unit<"Bq", 1 / second, kind_of> {} becquerel; +inline constexpr struct hertz : named_unit<"Hz", one / second, kind_of> {} hertz; +inline constexpr struct becquerel : named_unit<"Bq", one / second, kind_of> {} becquerel; ``` With the above, `hertz` can only be used for frequencies while becquerel should only be used for diff --git a/docs/users_guide/framework_basics/text_output.md b/docs/users_guide/framework_basics/text_output.md index c182a2cd6..da6cdec42 100644 --- a/docs/users_guide/framework_basics/text_output.md +++ b/docs/users_guide/framework_basics/text_output.md @@ -291,12 +291,12 @@ in the denominator), or never in which case a parenthesis will be added to enclo units. ```cpp -std::println("{:%Q %q}", 1 * (m / s)); // 1 m/s -std::println("{:%Q %q}", 1 * (kg / m / s2)); // 1 kg m⁻¹ s⁻² -std::println("{:%Q %aq}", 1 * (m / s)); // 1 m/s -std::println("{:%Q %aq}", 1 * (kg / m / s2)); // 1 kg/(m s²) -std::println("{:%Q %nq}", 1 * (m / s)); // 1 m s⁻¹ -std::println("{:%Q %nq}", 1 * (kg / m / s2)); // 1 kg m⁻¹ s⁻² +std::println("{:%Q %q}", 1 * m / s); // 1 m/s +std::println("{:%Q %q}", 1 * kg / m / s2); // 1 kg m⁻¹ s⁻² +std::println("{:%Q %aq}", 1 * m / s); // 1 m/s +std::println("{:%Q %aq}", 1 * kg / m / s2); // 1 kg/(m s²) +std::println("{:%Q %nq}", 1 * m / s); // 1 m s⁻¹ +std::println("{:%Q %nq}", 1 * kg / m / s2); // 1 kg m⁻¹ s⁻² ``` Also, there are a few options to separate the units being multiplied: @@ -319,6 +319,6 @@ to just use the `·` symbol as a separator. The `units-unit-symbol-separator` token allows us to obtain the following outputs: ```cpp -std::println("{:%Q %q}", 1 * (kg * m2 / s2)); // 1 kg m²/s² -std::println("{:%Q %dq}", 1 * (kg * m2 / s2)); // 1 kg⋅m²/s² +std::println("{:%Q %q}", 1 * kg * m2 / s2); // 1 kg m²/s² +std::println("{:%Q %dq}", 1 * kg * m2 / s2); // 1 kg⋅m²/s² ``` diff --git a/example/foot_pound_second.cpp b/example/foot_pound_second.cpp index 092f0d236..9177cd0c4 100644 --- a/example/foot_pound_second.cpp +++ b/example/foot_pound_second.cpp @@ -82,11 +82,11 @@ int main() auto bismark = Ship{.length{251. * m}, .draft{9.3 * m}, .beam{36 * m}, - .speed{56 * (km / h)}, + .speed{56 * km / h}, .mass{50'300 * t}, .mainGuns{380 * mm}, .shellMass{800 * kg}, - .shellSpeed{820. * (m / s)}, + .shellSpeed{820. * m / s}, .power{110.45 * kW}}; // USS Iowa, using units from the foot-pound-second system @@ -97,7 +97,7 @@ int main() .mass{57'540 * imperial::long_ton}, .mainGuns{16 * in}, .shellMass{2700 * lb}, - .shellSpeed{2690. * (ft / s)}, + .shellSpeed{2690. * ft / s}, .power{212'000 * hp}}; // HMS King George V, using units from the foot-pound-second system @@ -108,7 +108,7 @@ int main() .mass{42'245 * imperial::long_ton}, .mainGuns{14 * in}, .shellMass{1590 * lb}, - .shellSpeed{2483. * (ft / s)}, + .shellSpeed{2483. * ft / s}, .power{110'000 * hp}}; print_details("KMS Bismark, defined in appropriate units from the SI system", bismark); diff --git a/example/glide_computer.cpp b/example/glide_computer.cpp index 69231828b..c15309b9c 100644 --- a/example/glide_computer.cpp +++ b/example/glide_computer.cpp @@ -45,10 +45,10 @@ auto get_gliders() using namespace mp_units::si::unit_symbols; MP_UNITS_DIAGNOSTIC_PUSH MP_UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES - static const std::array gliders = {glider{"SZD-30 Pirat", {83 * (km / h), -0.7389 * (m / s)}}, - glider{"SZD-51 Junior", {80 * (km / h), -0.6349 * (m / s)}}, - glider{"SZD-48 Jantar Std 3", {110 * (km / h), -0.77355 * (m / s)}}, - glider{"SZD-56 Diana", {110 * (km / h), -0.63657 * (m / s)}}}; + static const std::array gliders = {glider{"SZD-30 Pirat", {83 * km / h, -0.7389 * m / s}}, + glider{"SZD-51 Junior", {80 * km / h, -0.6349 * m / s}}, + glider{"SZD-48 Jantar Std 3", {110 * km / h, -0.77355 * m / s}}, + glider{"SZD-56 Diana", {110 * km / h, -0.63657 * m / s}}}; MP_UNITS_DIAGNOSTIC_POP return gliders; } @@ -56,9 +56,9 @@ auto get_gliders() auto get_weather_conditions() { using namespace mp_units::si::unit_symbols; - static const std::array weather_conditions = {std::pair{"Good", weather{1900 * m, 4.3 * (m / s)}}, - std::pair{"Medium", weather{1550 * m, 2.8 * (m / s)}}, - std::pair{"Bad", weather{850 * m, 1.8 * (m / s)}}}; + static const std::array weather_conditions = {std::pair{"Good", weather{1900 * m, 4.3 * m / s}}, + std::pair{"Medium", weather{1550 * m, 2.8 * m / s}}, + std::pair{"Bad", weather{850 * m, 1.8 * m / s}}}; return weather_conditions; } @@ -164,7 +164,7 @@ void example() const auto waypoints = get_waypoints(); const auto weather_conditions = get_weather_conditions(); const task t = {waypoints[0], waypoints[1], waypoints[0]}; - const aircraft_tow tow = {400 * m, 1.6 * (m / s)}; + const aircraft_tow tow = {400 * m, 1.6 * m / s}; // TODO use C++20 date library when available // set `start_time` to 11:00 am today const timestamp start_time(std::chrono::system_clock::now()); diff --git a/example/hello_units.cpp b/example/hello_units.cpp index 7eeb44bd0..e537a7a6c 100644 --- a/example/hello_units.cpp +++ b/example/hello_units.cpp @@ -44,7 +44,7 @@ int main() using namespace mp_units::si::unit_symbols; using namespace mp_units::international::unit_symbols; - constexpr quantity v1 = 110 * (km / h); + constexpr quantity v1 = 110 * km / h; constexpr quantity v2 = 70 * mph; constexpr quantity v3 = avg_speed(220. * km, 2 * h); constexpr quantity v4 = avg_speed(isq::distance(140. * mi), 2 * isq::duration[h]); diff --git a/example/kalman_filter/kalman_filter-example_2.cpp b/example/kalman_filter/kalman_filter-example_2.cpp index b7b417146..ac748ca37 100644 --- a/example/kalman_filter/kalman_filter-example_2.cpp +++ b/example/kalman_filter/kalman_filter-example_2.cpp @@ -53,7 +53,7 @@ int main() using state = kalman::state, quantity>; const auto interval = isq::duration(5 * s); - const state initial = {30 * km, 40 * (m / s)}; + const state initial = {30 * km, 40 * m / s}; const quantity measurements[] = {30'110 * m, 30'265 * m, 30'740 * m, 30'750 * m, 31'135 * m, 31'015 * m, 31'180 * m, 31'610 * m, 31'960 * m, 31'865 * m}; diff --git a/example/kalman_filter/kalman_filter-example_3.cpp b/example/kalman_filter/kalman_filter-example_3.cpp index 30e11f435..1fb2e32f3 100644 --- a/example/kalman_filter/kalman_filter-example_3.cpp +++ b/example/kalman_filter/kalman_filter-example_3.cpp @@ -53,7 +53,7 @@ int main() using state = kalman::state, quantity>; const auto interval = isq::duration(5 * s); - const state initial = {30 * km, 50 * (m / s)}; + const state initial = {30 * km, 50 * m / s}; const quantity measurements[] = {30'160 * m, 30'365 * m, 30'890 * m, 31'050 * m, 31'785 * m, 32'215 * m, 33'130 * m, 34'510 * m, 36'010 * m, 37'265 * m}; diff --git a/example/kalman_filter/kalman_filter-example_4.cpp b/example/kalman_filter/kalman_filter-example_4.cpp index f0c4a2b26..cc5044eaf 100644 --- a/example/kalman_filter/kalman_filter-example_4.cpp +++ b/example/kalman_filter/kalman_filter-example_4.cpp @@ -53,7 +53,7 @@ int main() using state = kalman::state, quantity, quantity>; const auto interval = isq::duration(5. * s); - const state initial = {30 * km, 50 * (m / s), 0 * (m / s2)}; + const state initial = {30 * km, 50 * m / s, 0 * m / s2}; const quantity measurements[] = {30'160 * m, 30'365 * m, 30'890 * m, 31'050 * m, 31'785 * m, 32'215 * m, 33'130 * m, 34'510 * m, diff --git a/example/measurement.cpp b/example/measurement.cpp index c20d82249..539713881 100644 --- a/example/measurement.cpp +++ b/example/measurement.cpp @@ -134,7 +134,7 @@ void example() using namespace mp_units; using namespace mp_units::si::unit_symbols; - const auto acceleration = isq::acceleration(measurement{9.8, 0.1} * (m / s2)); + const auto acceleration = isq::acceleration(measurement{9.8, 0.1} * m / s2); const auto time = measurement{1.2, 0.1} * s; const QuantityOf auto velocity = acceleration * time; diff --git a/example/si_constants.cpp b/example/si_constants.cpp index d1a85a4a8..255f8054d 100644 --- a/example/si_constants.cpp +++ b/example/si_constants.cpp @@ -35,6 +35,7 @@ inline constexpr bool mp_units::is_vector = true; int main() { + using namespace mp_units; using namespace mp_units::si; using namespace mp_units::si::unit_symbols; @@ -52,7 +53,7 @@ int main() std::cout << MP_UNITS_STD_FMT::format("- Boltzmann constant: {} = {:%.6eQ %q}\n", 1. * si2019::boltzmann_constant, (1. * si2019::boltzmann_constant).in(J / K)); std::cout << MP_UNITS_STD_FMT::format("- Avogadro constant: {} = {:%.8eQ %q}\n", - 1. * si2019::avogadro_constant, (1. * si2019::avogadro_constant).in(1 / mol)); + 1. * si2019::avogadro_constant, (1. * si2019::avogadro_constant).in(one / mol)); std::cout << MP_UNITS_STD_FMT::format("- luminous efficacy: {} = {}\n", 1. * si2019::luminous_efficacy, (1. * si2019::luminous_efficacy).in(lm / W)); } diff --git a/example/spectroscopy_units.cpp b/example/spectroscopy_units.cpp index 6cf9e953f..363605a1a 100644 --- a/example/spectroscopy_units.cpp +++ b/example/spectroscopy_units.cpp @@ -61,7 +61,7 @@ template T1, QuantityOf T2, QuantityOf< void print_line_si(const std::tuple& t) { MP_UNITS_STD_FMT::println("| {:<15} | {:<15} | {:<15} | {:<15} | {:<15} |", std::get<0>(t).in(eV), - std::get<1>(t).in(1 / cm), std::get<2>(t).in(THz), std::get<3>(t).in(K), + std::get<1>(t).in(one / cm), std::get<2>(t).in(THz), std::get<3>(t).in(K), std::get<4>(t).in(um)); } @@ -71,7 +71,7 @@ int main() const auto t1 = std::make_tuple(q1, isq::wavenumber(q1 / (h * c)), isq::frequency(q1 / h), isq::thermodynamic_temperature(q1 / kb), isq::wavelength(h * c / q1)); - const auto q2 = 1. * isq::wavenumber[1 / cm]; + const auto q2 = 1. * isq::wavenumber[one / cm]; const auto t2 = std::make_tuple(isq::energy(q2 * h * c), q2, isq::frequency(q2 * c), isq::thermodynamic_temperature(q2 * h * c / kb), isq::wavelength(1 / q2)); diff --git a/example/storage_tank.cpp b/example/storage_tank.cpp index a7bf2e038..d975e9e0e 100644 --- a/example/storage_tank.cpp +++ b/example/storage_tank.cpp @@ -53,7 +53,7 @@ QUANTITY_SPEC(horizontal_length, isq::length); QUANTITY_SPEC(horizontal_area, isq::area, horizontal_length* isq::width); inline constexpr auto g = 1 * si::standard_gravity; -inline constexpr auto air_density = isq::mass_density(1.225 * (kg / m3)); +inline constexpr auto air_density = isq::mass_density(1.225 * kg / m3); class StorageTank { quantity base_; @@ -114,7 +114,7 @@ int main() { const quantity height = isq::height(200 * mm); auto tank = RectangularStorageTank(horizontal_length(1'000 * mm), isq::width(500 * mm), height); - tank.set_contents_density(1'000 * isq::mass_density[kg / m3]); + tank.set_contents_density(1'000 * kg / m3); const auto duration = std::chrono::seconds{200}; const quantity fill_time = value_cast(quantity{duration}); // time since starting fill diff --git a/src/core/include/mp-units/dimension.h b/src/core/include/mp-units/dimension.h index 4c9c07961..a0a4dc8bf 100644 --- a/src/core/include/mp-units/dimension.h +++ b/src/core/include/mp-units/dimension.h @@ -88,7 +88,7 @@ using type_list_of_base_dimension_less = expr_less; * For example: * * @code{.cpp} - * using frequency = decltype(1 / dim_time); + * using frequency = decltype(inverse(dim_time)); * using speed = decltype(dim_length / dim_time); * using acceleration = decltype(dim_speed / dim_time); * using force = decltype(dim_mass * dim_acceleration); @@ -150,22 +150,14 @@ template Rhs{}); } -template -[[nodiscard]] consteval Dimension auto operator/(int value, D) -{ - gsl_Expects(value == 1); - return detail::expr_invert(D{}); -} - -template -[[nodiscard]] consteval Dimension auto operator/(D, int) = delete; - template [[nodiscard]] consteval bool operator==(Lhs, Rhs) { return is_same_v; } +[[nodiscard]] consteval Dimension auto inverse(Dimension auto d) { return dimension_one / d; } + /** * @brief Computes the value of a dimension raised to the `Num/Den` power * diff --git a/src/core/include/mp-units/quantity.h b/src/core/include/mp-units/quantity.h index 96178dc98..2ebc1eddd 100644 --- a/src/core/include/mp-units/quantity.h +++ b/src/core/include/mp-units/quantity.h @@ -432,7 +432,7 @@ template } template - requires(!Quantity) && + requires(!Quantity) && (!Reference) && detail::InvokeResultOf, Rep, const Value&> [[nodiscard]] constexpr Quantity auto operator*(const quantity& q, const Value& v) { @@ -440,7 +440,7 @@ template } template - requires(!Quantity) && + requires(!Quantity) && (!Reference) && detail::InvokeResultOf, const Value&, Rep> [[nodiscard]] constexpr Quantity auto operator*(const Value& v, const quantity& q) { @@ -456,7 +456,7 @@ template } template - requires(!Quantity) && + requires(!Quantity) && (!Reference) && detail::InvokeResultOf, Rep, const Value&> [[nodiscard]] constexpr Quantity auto operator/(const quantity& q, const Value& v) { @@ -465,7 +465,7 @@ template } template - requires(!Quantity) && + requires(!Quantity) && (!Reference) && detail::InvokeResultOf, const Value&, Rep> [[nodiscard]] constexpr Quantity auto operator/(const Value& v, const quantity& q) { diff --git a/src/core/include/mp-units/quantity_spec.h b/src/core/include/mp-units/quantity_spec.h index ef224b9e2..b85db0cce 100644 --- a/src/core/include/mp-units/quantity_spec.h +++ b/src/core/include/mp-units/quantity_spec.h @@ -395,7 +395,7 @@ struct quantity_spec : quantity_spec { * For example: * * @code{.cpp} - * auto frequency = 1 / period_duration; + * auto frequency = inverse(period_duration); * auto area = pow<2>(length); * auto speed = distance / duration; * auto velocity = position_vector / duration; @@ -497,7 +497,7 @@ template template [[nodiscard]] consteval QuantitySpec auto operator*(Lhs lhs, Rhs rhs) { - return clone_kind_of( + return detail::clone_kind_of( detail::expr_multiply( remove_kind(lhs), remove_kind(rhs))); } @@ -505,20 +505,11 @@ template template [[nodiscard]] consteval QuantitySpec auto operator/(Lhs lhs, Rhs rhs) { - return clone_kind_of( + return detail::clone_kind_of( detail::expr_divide( remove_kind(lhs), remove_kind(rhs))); } -template -[[nodiscard]] consteval QuantitySpec auto operator/(int value, QS qs) -{ - gsl_Expects(value == 1); - return clone_kind_of(detail::expr_invert(qs)); -} - -[[nodiscard]] consteval QuantitySpec auto operator/(QuantitySpec auto, int) = delete; - template [[nodiscard]] consteval bool operator==(Lhs, Rhs) { @@ -537,6 +528,8 @@ template return is_same_v>; } +[[nodiscard]] consteval QuantitySpec auto inverse(QuantitySpec auto q) { return dimensionless / q; } + /** * @brief Computes the value of a quantity specification raised to the `Num/Den` power diff --git a/src/core/include/mp-units/reference.h b/src/core/include/mp-units/reference.h index 1633336bd..41ac47876 100644 --- a/src/core/include/mp-units/reference.h +++ b/src/core/include/mp-units/reference.h @@ -119,6 +119,8 @@ struct reference { return {}; } + [[nodiscard]] friend consteval reference inverse(reference) { return {}; } + /** * @brief Computes the value of a reference raised to the `Num/Den` power * @@ -176,12 +178,48 @@ template Rep> class quantity; template + requires RepresentationOf, get_quantity_spec(R{}).character> [[nodiscard]] constexpr quantity> operator*(Rep&& lhs, R) { return make_quantity(std::forward(lhs)); } -void /*Use `q * (1 * r)` rather than `q * r`.*/ operator*(Quantity auto, Reference auto) = delete; +template + requires RepresentationOf, get_quantity_spec(R{}).character> +[[nodiscard]] constexpr quantity> operator/(Rep&& lhs, R) +{ + return make_quantity(std::forward(lhs)); +} + +template + requires RepresentationOf, get_quantity_spec(R{}).character> +constexpr auto operator*(R, Rep&&) = delete; + +template + requires RepresentationOf, get_quantity_spec(R{}).character> +constexpr auto operator/(R, Rep&&) = delete; + +template + requires Quantity> +[[nodiscard]] constexpr Quantity auto operator*(Q&& q, R) +{ + return make_quantity::reference * R{}>(std::forward(q).numerical_value_); +} + +template + requires Quantity> +[[nodiscard]] constexpr Quantity auto operator/(Q&& q, R) +{ + return make_quantity::reference / R{}>(std::forward(q).numerical_value_); +} + +template + requires Quantity> +constexpr auto operator*(R, Q&& q) = delete; + +template + requires Quantity> +constexpr auto operator/(R, Q&& q) = delete; [[nodiscard]] consteval AssociatedUnit auto common_reference(AssociatedUnit auto u1, AssociatedUnit auto u2, AssociatedUnit auto... rest) diff --git a/src/core/include/mp-units/unit.h b/src/core/include/mp-units/unit.h index ca3068cff..50c38a2ce 100644 --- a/src/core/include/mp-units/unit.h +++ b/src/core/include/mp-units/unit.h @@ -77,7 +77,7 @@ inline constexpr bool is_specialization_of_scaled_unit> = true * @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", 1 / second> {} hertz; + * 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 {} degree_Celsius; * inline constexpr struct minute : named_unit<"min", mag<60> * second> {} minute; @@ -212,8 +212,8 @@ struct is_one : std::false_type {}; * For example: * * @code{.cpp} - * static_assert(is_of_type<1 / second, derived_unit>>); - * static_assert(is_of_type<1 / (1 / second), second>); + * static_assert(is_of_type>>); + * static_assert(is_of_type); * static_assert(is_of_type); * static_assert(is_of_type>>); * static_assert(is_of_type>); @@ -430,6 +430,15 @@ template return detail::expr_multiply(lhs, rhs); } +/** + * Returns the result of multiplication with an inverse unit. + */ +template +[[nodiscard]] MP_UNITS_CONSTEVAL Unit auto operator/(M mag, const U u) +{ + return mag * inverse(u); +} + /** * `scaled_unit` specializations have priority in this operation. This means that the library framework * prevents passing it as an element to the `derived_unit`. In such case only the reference unit is passed @@ -448,13 +457,8 @@ template return detail::expr_divide(lhs, rhs); } -[[nodiscard]] MP_UNITS_CONSTEVAL Unit auto operator/(int value, Unit auto u) -{ - gsl_Expects(value == 1); - return detail::expr_invert(u); -} +[[nodiscard]] MP_UNITS_CONSTEVAL Unit auto inverse(Unit auto u) { return one / u; } -[[nodiscard]] consteval Unit auto operator/(Unit auto, int) = delete; namespace detail { diff --git a/src/systems/cgs/include/mp-units/systems/cgs/cgs.h b/src/systems/cgs/include/mp-units/systems/cgs/cgs.h index 69f4dcf8b..9e91b6da8 100644 --- a/src/systems/cgs/include/mp-units/systems/cgs/cgs.h +++ b/src/systems/cgs/include/mp-units/systems/cgs/cgs.h @@ -37,7 +37,7 @@ inline constexpr struct erg : named_unit<"erg", dyne * centimetre> {} erg; inline constexpr struct barye : named_unit<"Ba", gram / (centimetre * square(second))> {} barye; inline constexpr struct poise : named_unit<"P", gram / (centimetre * second)> {} poise; inline constexpr struct stokes : named_unit<"St", square(centimetre) / second> {} stokes; -inline constexpr struct kayser : named_unit<"K", 1 / centimetre> {} kayser; +inline constexpr struct kayser : named_unit<"K", one / centimetre> {} kayser; // clang-format on namespace unit_symbols { diff --git a/src/systems/iec80000/include/mp-units/systems/iec80000/quantities.h b/src/systems/iec80000/include/mp-units/systems/iec80000/quantities.h index c436943a3..d28064ddf 100644 --- a/src/systems/iec80000/include/mp-units/systems/iec80000/quantities.h +++ b/src/systems/iec80000/include/mp-units/systems/iec80000/quantities.h @@ -42,21 +42,21 @@ inline constexpr auto traffic_load = traffic_carried_intensity; QUANTITY_SPEC(mean_queue_length, dimensionless); QUANTITY_SPEC(loss_probability, dimensionless); QUANTITY_SPEC(waiting_probability, dimensionless); -QUANTITY_SPEC(call_intensity, 1 / isq::duration); +QUANTITY_SPEC(call_intensity, inverse(isq::duration)); inline constexpr auto calling_rate = call_intensity; QUANTITY_SPEC(completed_call_intensity, call_intensity); QUANTITY_SPEC(storage_capacity, dimensionless, is_kind); inline constexpr auto storage_size = storage_capacity; QUANTITY_SPEC(equivalent_binary_storage_capacity, storage_capacity); QUANTITY_SPEC(transfer_rate, storage_capacity / isq::duration); -QUANTITY_SPEC(period_of_data_elements, isq::period, 1 / transfer_rate); +QUANTITY_SPEC(period_of_data_elements, isq::period, inverse(transfer_rate)); QUANTITY_SPEC(binary_digit_rate, transfer_rate); inline constexpr auto bit_rate = binary_digit_rate; -QUANTITY_SPEC(period_of_binary_digits, isq::period, 1 / binary_digit_rate); +QUANTITY_SPEC(period_of_binary_digits, isq::period, inverse(binary_digit_rate)); inline constexpr auto bit_period = period_of_binary_digits; QUANTITY_SPEC(equivalent_binary_digit_rate, binary_digit_rate); inline constexpr auto equivalent_bit_rate = bit_rate; -QUANTITY_SPEC(modulation_rate, 1 / isq::duration); +QUANTITY_SPEC(modulation_rate, inverse(isq::duration)); inline constexpr auto line_digit_rate = modulation_rate; QUANTITY_SPEC(quantizing_distortion_power, isq::power); QUANTITY_SPEC(carrier_power, isq::power); diff --git a/src/systems/iec80000/include/mp-units/systems/iec80000/units.h b/src/systems/iec80000/include/mp-units/systems/iec80000/units.h index 2bbe05cfd..2f80e1679 100644 --- a/src/systems/iec80000/include/mp-units/systems/iec80000/units.h +++ b/src/systems/iec80000/include/mp-units/systems/iec80000/units.h @@ -33,7 +33,7 @@ inline constexpr struct erlang : named_unit<"E", kind_of> {} inline constexpr struct bit : named_unit<"bit", one, kind_of> {} bit; inline constexpr struct octet : named_unit<"o", mag<8> * bit> {} octet; inline constexpr struct byte : named_unit<"B", mag<8> * bit> {} byte; -inline constexpr struct baud : named_unit<"Bd", 1 / si::second, kind_of> {} baud; +inline constexpr struct baud : named_unit<"Bd", one / si::second, kind_of> {} baud; // clang-format on } // namespace mp_units::iec80000 diff --git a/src/systems/isq/include/mp-units/systems/isq/atomic_and_nuclear_physics.h b/src/systems/isq/include/mp-units/systems/isq/atomic_and_nuclear_physics.h index 7493e0f3d..24075900b 100644 --- a/src/systems/isq/include/mp-units/systems/isq/atomic_and_nuclear_physics.h +++ b/src/systems/isq/include/mp-units/systems/isq/atomic_and_nuclear_physics.h @@ -30,7 +30,7 @@ namespace mp_units::isq { // TODO Add all the remaining ISQ definitions -QUANTITY_SPEC(activity, 1 / duration); +QUANTITY_SPEC(activity, inverse(duration)); QUANTITY_SPEC(absorbed_dose, energy / mass); QUANTITY_SPEC(ionizing_radiation_quality_factor, dimensionless); QUANTITY_SPEC(dose_equivalent, absorbed_dose* ionizing_radiation_quality_factor); diff --git a/src/systems/isq/include/mp-units/systems/isq/electromagnetism.h b/src/systems/isq/include/mp-units/systems/isq/electromagnetism.h index 03294a368..2ba2aa9fc 100644 --- a/src/systems/isq/include/mp-units/systems/isq/electromagnetism.h +++ b/src/systems/isq/include/mp-units/systems/isq/electromagnetism.h @@ -63,7 +63,7 @@ QUANTITY_SPEC(phase_speed_of_electromagnetic_waves, angular_frequency / angular_ QUANTITY_SPEC(speed_of_light_in_vacuum, speed); inline constexpr auto light_speed_in_vacuum = speed_of_light_in_vacuum; inline constexpr auto luminal_speed = speed_of_light_in_vacuum; -QUANTITY_SPEC(electric_constant, 1 / (magnetic_constant * pow<2>(speed_of_light_in_vacuum))); +QUANTITY_SPEC(electric_constant, inverse(magnetic_constant* pow<2>(speed_of_light_in_vacuum))); inline constexpr auto permittivity_of_vacuum = electric_constant; QUANTITY_SPEC(permittivity, electric_flux_density / electric_field_strength, quantity_character::scalar); QUANTITY_SPEC(relative_permittivity, dimensionless, permittivity / electric_constant); @@ -101,18 +101,18 @@ QUANTITY_SPEC(magnetomotive_force, electric_current, magnetic_field_strength* po QUANTITY_SPEC(current_linkage, electric_current); QUANTITY_SPEC(number_of_turns_in_a_winding, dimensionless); QUANTITY_SPEC(reluctance, magnetic_tension / magnetic_flux); -QUANTITY_SPEC(permeance, 1 / reluctance); +QUANTITY_SPEC(permeance, inverse(reluctance)); QUANTITY_SPEC(inductance, linked_flux / electric_current); inline constexpr auto self_inductance = inductance; QUANTITY_SPEC(mutual_inductance, linked_flux / electric_current); QUANTITY_SPEC(coupling_factor, dimensionless, mutual_inductance / pow<1, 2>(pow<2>(self_inductance))); QUANTITY_SPEC(leakage_factor, dimensionless, pow<2>(coupling_factor)); QUANTITY_SPEC(conductivity, electric_current_density / electric_field_strength, quantity_character::scalar); -QUANTITY_SPEC(resistivity, 1 / conductivity); +QUANTITY_SPEC(resistivity, inverse(conductivity)); QUANTITY_SPEC(electromagnetism_power, power, voltage* electric_current); inline constexpr auto instantaneous_power = electromagnetism_power; QUANTITY_SPEC(resistance, voltage / electric_current); -QUANTITY_SPEC(conductance, 1 / resistance); +QUANTITY_SPEC(conductance, inverse(resistance)); QUANTITY_SPEC(phase_difference, phase_angle); QUANTITY_SPEC(electric_current_phasor, electric_current); QUANTITY_SPEC(voltage_phasor, voltage); @@ -121,15 +121,15 @@ inline constexpr auto complex_impedance = impedance; QUANTITY_SPEC(resistance_to_alternating_current, impedance); QUANTITY_SPEC(reactance, impedance); QUANTITY_SPEC(modulus_of_impedance, impedance); -QUANTITY_SPEC(admittance, 1 / impedance); +QUANTITY_SPEC(admittance, inverse(impedance)); inline constexpr auto complex_admittance = admittance; QUANTITY_SPEC(conductance_for_alternating_current, admittance); QUANTITY_SPEC(susceptance, admittance); QUANTITY_SPEC(modulus_of_admittance, admittance); QUANTITY_SPEC(quality_factor, dimensionless, reactance / resistance); -QUANTITY_SPEC(loss_factor, dimensionless, 1 / quality_factor); +QUANTITY_SPEC(loss_factor, dimensionless, inverse(quality_factor)); QUANTITY_SPEC(loss_angle, angular_measure); -QUANTITY_SPEC(active_power, 1 / period * (instantaneous_power * time)); +QUANTITY_SPEC(active_power, inverse(period) * (instantaneous_power * time)); QUANTITY_SPEC(apparent_power, voltage* electric_current); QUANTITY_SPEC(power_factor, dimensionless, active_power / apparent_power); QUANTITY_SPEC(complex_power, voltage_phasor* electric_current_phasor); diff --git a/src/systems/isq/include/mp-units/systems/isq/mechanics.h b/src/systems/isq/include/mp-units/systems/isq/mechanics.h index 4d0a57b8a..fd0795507 100644 --- a/src/systems/isq/include/mp-units/systems/isq/mechanics.h +++ b/src/systems/isq/include/mp-units/systems/isq/mechanics.h @@ -30,7 +30,7 @@ namespace mp_units::isq { QUANTITY_SPEC(mass_density, mass / volume); inline constexpr auto density = mass_density; -QUANTITY_SPEC(specific_volume, 1 / mass_density); +QUANTITY_SPEC(specific_volume, inverse(mass_density)); QUANTITY_SPEC(relative_mass_density, mass_density / mass_density); inline constexpr auto relative_density = relative_mass_density; QUANTITY_SPEC(surface_mass_density, mass / area); @@ -70,7 +70,7 @@ QUANTITY_SPEC(modulus_of_rigidity, shear_stress / shear_strain); inline constexpr auto shear_modulus = modulus_of_rigidity; QUANTITY_SPEC(modulus_of_compression, pressure / relative_volume_strain); inline constexpr auto bulk_modulus = modulus_of_compression; -QUANTITY_SPEC(compressibility, 1 / volume * (volume / pressure)); +QUANTITY_SPEC(compressibility, inverse(volume) * (volume / pressure)); QUANTITY_SPEC(second_axial_moment_of_area, pow<2>(radial_distance) * area); QUANTITY_SPEC(second_polar_moment_of_area, pow<2>(radial_distance) * area); QUANTITY_SPEC(section_modulus, second_axial_moment_of_area / radial_distance); diff --git a/src/systems/isq/include/mp-units/systems/isq/space_and_time.h b/src/systems/isq/include/mp-units/systems/isq/space_and_time.h index 0c3ef5587..c60be5fd7 100644 --- a/src/systems/isq/include/mp-units/systems/isq/space_and_time.h +++ b/src/systems/isq/include/mp-units/systems/isq/space_and_time.h @@ -42,7 +42,7 @@ QUANTITY_SPEC(radial_distance, distance); QUANTITY_SPEC(position_vector, length, quantity_character::vector); QUANTITY_SPEC(displacement, length, quantity_character::vector); QUANTITY_SPEC(radius_of_curvature, radius); -QUANTITY_SPEC(curvature, 1 / radius_of_curvature); +QUANTITY_SPEC(curvature, inverse(radius_of_curvature)); QUANTITY_SPEC(area, pow<2>(length)); QUANTITY_SPEC(volume, pow<3>(length)); QUANTITY_SPEC(angular_measure, dimensionless, arc_length / radius, is_kind); @@ -61,25 +61,25 @@ QUANTITY_SPEC(period_duration, duration); inline constexpr auto period = period_duration; QUANTITY_SPEC(time_constant, duration); QUANTITY_SPEC(rotation, dimensionless); -QUANTITY_SPEC(frequency, 1 / period_duration); +QUANTITY_SPEC(frequency, inverse(period_duration)); QUANTITY_SPEC(rotational_frequency, rotation / duration); QUANTITY_SPEC(angular_frequency, phase_angle / duration); QUANTITY_SPEC(wavelength, length); -QUANTITY_SPEC(repetency, 1 / wavelength); +QUANTITY_SPEC(repetency, inverse(wavelength)); inline constexpr auto wavenumber = repetency; QUANTITY_SPEC(wave_vector, repetency, quantity_character::vector); -QUANTITY_SPEC(angular_repetency, 1 / wavelength); +QUANTITY_SPEC(angular_repetency, inverse(wavelength)); inline constexpr auto angular_wavenumber = angular_repetency; QUANTITY_SPEC(phase_velocity, angular_frequency / angular_repetency); inline constexpr auto phase_speed = phase_velocity; QUANTITY_SPEC(group_velocity, angular_frequency / angular_repetency); inline constexpr auto group_speed = group_velocity; -QUANTITY_SPEC(damping_coefficient, 1 / time_constant); +QUANTITY_SPEC(damping_coefficient, inverse(time_constant)); QUANTITY_SPEC(logarithmic_decrement, dimensionless, damping_coefficient* period_duration); -QUANTITY_SPEC(attenuation, 1 / distance); +QUANTITY_SPEC(attenuation, inverse(distance)); inline constexpr auto extinction = attenuation; QUANTITY_SPEC(phase_coefficient, phase_angle / path_length); -QUANTITY_SPEC(propagation_coefficient, 1 / length); // γ = α + iβ where α denotes attenuation - // and β the phase coefficient of a plane wave +QUANTITY_SPEC(propagation_coefficient, inverse(length)); // γ = α + iβ where α denotes attenuation + // and β the phase coefficient of a plane wave } // namespace mp_units::isq diff --git a/src/systems/isq/include/mp-units/systems/isq/thermodynamics.h b/src/systems/isq/include/mp-units/systems/isq/thermodynamics.h index 1c59c05e6..3a543a6d5 100644 --- a/src/systems/isq/include/mp-units/systems/isq/thermodynamics.h +++ b/src/systems/isq/include/mp-units/systems/isq/thermodynamics.h @@ -30,12 +30,12 @@ namespace mp_units::isq { QUANTITY_SPEC(Celsius_temperature, thermodynamic_temperature); // TODO should we account for T0 here? -QUANTITY_SPEC(linear_expansion_coefficient, 1 / length * (length / thermodynamic_temperature)); -QUANTITY_SPEC(cubic_expansion_coefficient, 1 / volume * (volume / thermodynamic_temperature)); -QUANTITY_SPEC(relative_pressure_coefficient, 1 / pressure * (pressure / thermodynamic_temperature)); +QUANTITY_SPEC(linear_expansion_coefficient, inverse(length) * (length / thermodynamic_temperature)); +QUANTITY_SPEC(cubic_expansion_coefficient, inverse(volume) * (volume / thermodynamic_temperature)); +QUANTITY_SPEC(relative_pressure_coefficient, inverse(pressure) * (pressure / thermodynamic_temperature)); QUANTITY_SPEC(pressure_coefficient, pressure / thermodynamic_temperature); -QUANTITY_SPEC(isothermal_compressibility, 1 / volume * (volume / pressure)); // TODO how to handle "negative" part -QUANTITY_SPEC(isentropic_compressibility, 1 / volume * (volume / pressure)); // TODO how to handle "negative" part +QUANTITY_SPEC(isothermal_compressibility, inverse(volume) * (volume / pressure)); // TODO how to handle "negative" part +QUANTITY_SPEC(isentropic_compressibility, inverse(volume) * (volume / pressure)); // TODO how to handle "negative" part // energy definition moved to mechanics QUANTITY_SPEC(heat, energy); inline constexpr auto amount_of_heat = heat; @@ -45,10 +45,10 @@ QUANTITY_SPEC(density_of_heat_flow_rate, heat_flow_rate / area); QUANTITY_SPEC(thermal_conductivity, density_of_heat_flow_rate*(length / thermodynamic_temperature)); QUANTITY_SPEC(coefficient_of_heat_transfer, density_of_heat_flow_rate / thermodynamic_temperature); QUANTITY_SPEC(surface_coefficient_of_heat_transfer, density_of_heat_flow_rate / thermodynamic_temperature); -QUANTITY_SPEC(thermal_insulance, 1 / coefficient_of_heat_transfer); +QUANTITY_SPEC(thermal_insulance, inverse(coefficient_of_heat_transfer)); inline constexpr auto coefficient_of_thermal_insulance = thermal_insulance; QUANTITY_SPEC(thermal_resistance, thermodynamic_temperature / heat_flow_rate); -QUANTITY_SPEC(thermal_conductance, 1 / thermal_resistance); +QUANTITY_SPEC(thermal_conductance, inverse(thermal_resistance)); QUANTITY_SPEC(heat_capacity, heat / thermodynamic_temperature); QUANTITY_SPEC(specific_heat_capacity, heat_capacity / mass); QUANTITY_SPEC(specific_heat_capacity_at_constant_pressure, specific_heat_capacity); diff --git a/src/systems/natural/include/mp-units/systems/natural/natural.h b/src/systems/natural/include/mp-units/systems/natural/natural.h index 3d6143360..b07386109 100644 --- a/src/systems/natural/include/mp-units/systems/natural/natural.h +++ b/src/systems/natural/include/mp-units/systems/natural/natural.h @@ -36,8 +36,8 @@ inline constexpr struct electronvolt : named_unit<"eV"> {} electronvolt; inline constexpr struct gigaelectronvolt : decltype(si::giga) {} gigaelectronvolt; // system references -inline constexpr struct time : system_reference {} time; -inline constexpr struct length : system_reference {} length; +inline constexpr struct time : system_reference {} time; +inline constexpr struct length : system_reference {} length; inline constexpr struct mass : system_reference {} mass; inline constexpr struct velocity : system_reference {} velocity; inline constexpr struct speed : system_reference {} speed; diff --git a/src/systems/si/include/mp-units/systems/si/constants.h b/src/systems/si/include/mp-units/systems/si/constants.h index a0ad268d7..b342ba5d5 100644 --- a/src/systems/si/include/mp-units/systems/si/constants.h +++ b/src/systems/si/include/mp-units/systems/si/constants.h @@ -41,7 +41,7 @@ inline constexpr struct elementary_charge : inline constexpr struct boltzmann_constant : named_unit<"k", mag * mag_power<10, -23> * joule / kelvin> {} boltzmann_constant; inline constexpr struct avogadro_constant : - named_unit<"N_A", mag * mag_power<10, 23> * (1 / mole)> {} avogadro_constant; + named_unit<"N_A", mag * mag_power<10, 23> / mole> {} avogadro_constant; inline constexpr struct luminous_efficacy : named_unit<"K_cd", mag<683> * lumen / watt> {} luminous_efficacy; // clang-format on diff --git a/src/systems/si/include/mp-units/systems/si/units.h b/src/systems/si/include/mp-units/systems/si/units.h index 543b0cf72..c9f517f03 100644 --- a/src/systems/si/include/mp-units/systems/si/units.h +++ b/src/systems/si/include/mp-units/systems/si/units.h @@ -46,7 +46,7 @@ inline constexpr struct candela : named_unit<"cd", kind_of> {} radian; inline constexpr struct steradian : named_unit<"sr", square(metre) / square(metre), kind_of> {} steradian; -inline constexpr struct hertz : named_unit<"Hz", 1 / second, kind_of> {} hertz; +inline constexpr struct hertz : named_unit<"Hz", one / second, kind_of> {} hertz; inline constexpr struct newton : named_unit<"N", kilogram * metre / square(second)> {} newton; #ifdef pascal #pragma push_macro("pascal") @@ -64,14 +64,14 @@ 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 {} ohm; -inline constexpr struct siemens : named_unit<"S", 1 / ohm> {} siemens; +inline constexpr struct siemens : named_unit<"S", one / ohm> {} siemens; inline constexpr struct weber : named_unit<"Wb", volt * second> {} weber; inline constexpr struct tesla : named_unit<"T", weber / square(metre)> {} tesla; inline constexpr struct henry : named_unit<"H", weber / ampere> {} henry; inline constexpr struct degree_Celsius : named_unit {} degree_Celsius; inline constexpr struct lumen : named_unit<"lm", candela * steradian> {} lumen; inline constexpr struct lux : named_unit<"lx", lumen / square(metre)> {} lux; -inline constexpr struct becquerel : named_unit<"Bq", 1 / second, kind_of> {} becquerel; +inline constexpr struct becquerel : named_unit<"Bq", one / second, kind_of> {} becquerel; inline constexpr struct gray : named_unit<"Gy", joule / kilogram, kind_of> {} gray; inline constexpr struct sievert : named_unit<"Sv", joule / kilogram, kind_of> {} sievert; inline constexpr struct katal : named_unit<"kat", mole / second> {} katal; diff --git a/test/unit_test/runtime/fmt_test.cpp b/test/unit_test/runtime/fmt_test.cpp index 660311404..bda7b9360 100644 --- a/test/unit_test/runtime/fmt_test.cpp +++ b/test/unit_test/runtime/fmt_test.cpp @@ -167,7 +167,7 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]") SECTION("compressibility") { - const auto q = 123 * isq::compressibility[1 / Pa]; + const auto q = 123 * isq::compressibility[one / Pa]; os << q; SECTION("iostream") { CHECK(os.str() == "123 1/Pa"); } diff --git a/test/unit_test/runtime/linear_algebra_test.cpp b/test/unit_test/runtime/linear_algebra_test.cpp index 77f023ef3..986204b94 100644 --- a/test/unit_test/runtime/linear_algebra_test.cpp +++ b/test/unit_test/runtime/linear_algebra_test.cpp @@ -311,7 +311,7 @@ TEST_CASE("vector of quantities", "[la]") SECTION("to scalar magnitude") { - const vector> v = {2 * (km / h), 3 * (km / h), 6 * (km / h)}; + const vector> v = {2 * km / h, 3 * km / h, 6 * km / h}; const auto speed = get_magnitude(v); CHECK(speed.numerical_value_ref_in(km / h) == 7); } @@ -384,12 +384,12 @@ TEST_CASE("vector of quantities", "[la]") SECTION("multiply by scalar quantity") { - const vector> v = {1 * (m / s), 2 * (m / s), 3 * (m / s)}; + const vector> v = {1 * m / s, 2 * m / s, 3 * m / s}; SECTION("integral") { const auto mass = 2 * isq::mass[kg]; - const auto result = vector>{2 * (N * s), 4 * (N * s), 6 * (N * s)}; + const auto result = vector>{2 * N * s, 4 * N * s, 6 * N * s}; SECTION("derived_quantity_spec") { @@ -417,7 +417,7 @@ TEST_CASE("vector of quantities", "[la]") SECTION("floating-point") { const auto mass = 0.5 * isq::mass[kg]; - const auto result = vector>{0.5 * (N * s), 1. * (N * s), 1.5 * (N * s)}; + const auto result = vector>{0.5 * N * s, 1. * N * s, 1.5 * N * s}; SECTION("derived_quantity_spec") { @@ -453,7 +453,7 @@ TEST_CASE("vector of quantities", "[la]") SECTION("derived_quantity_spec") { - CHECK(pos / dur == vector>{15 * (km / h), 10 * (km / h), 5 * (km / h)}); + CHECK(pos / dur == vector>{15 * km / h, 10 * km / h, 5 * km / h}); } // no way to apply quantity_cast to sub-components @@ -461,7 +461,7 @@ TEST_CASE("vector of quantities", "[la]") SECTION("quantity of velocity") { const vector> v = pos / dur; - CHECK(v == vector>{15 * (km / h), 10 * (km / h), 5 * (km / h)}); + CHECK(v == vector>{15 * km / h, 10 * km / h, 5 * km / h}); } } @@ -471,8 +471,7 @@ TEST_CASE("vector of quantities", "[la]") SECTION("derived_quantity_spec") { - CHECK(pos / dur == - vector>{60. * (km / h), 40. * (km / h), 20. * (km / h)}); + CHECK(pos / dur == vector>{60. * km / h, 40. * km / h, 20. * km / h}); } // no way to apply quantity_cast to sub-components @@ -480,7 +479,7 @@ TEST_CASE("vector of quantities", "[la]") SECTION("quantity of velocity") { const vector> v = pos / dur; - CHECK(v == vector>{60. * (km / h), 40. * (km / h), 20. * (km / h)}); + CHECK(v == vector>{60. * km / h, 40. * km / h, 20. * km / h}); } } } @@ -490,7 +489,6 @@ TEST_CASE("vector of quantities", "[la]") const vector> r = {3 * m, 0 * m, 0 * m}; const vector> f = {0 * N, 10 * N, 0 * N}; - CHECK(cross_product(r, f) == - vector>{0 * (N * m), 0 * (N * m), 30 * (N * m)}); + CHECK(cross_product(r, f) == vector>{0 * N * m, 0 * N * m, 30 * N * m}); } } diff --git a/test/unit_test/static/cgs_test.cpp b/test/unit_test/static/cgs_test.cpp index e0b36fffb..c58c58859 100644 --- a/test/unit_test/static/cgs_test.cpp +++ b/test/unit_test/static/cgs_test.cpp @@ -40,24 +40,24 @@ using namespace mp_units::cgs::unit_symbols; static_assert(isq::length(100 * cm) == isq::length(1 * si::metre)); static_assert(isq::mass(1000 * g) == isq::mass(1 * si::kilogram)); static_assert(isq::time(1 * s) == isq::time(1 * si::second)); -static_assert(isq::speed(100 * (cm / s)) == isq::speed(1 * (si::metre / si::second))); -static_assert(isq::acceleration(100 * Gal) == isq::acceleration(1 * (si::metre / square(si::second)))); +static_assert(isq::speed(100 * cm / s) == isq::speed(1 * si::metre / si::second)); +static_assert(isq::acceleration(100 * Gal) == isq::acceleration(1 * si::metre / square(si::second))); static_assert(isq::force(100'000 * dyn) == isq::force(1 * si::newton)); static_assert(isq::energy(10'000'000 * erg) == isq::energy(1 * si::joule)); -static_assert(isq::power(10'000'000 * (erg / s)) == isq::power(1 * si::watt)); +static_assert(isq::power(10'000'000 * erg / s) == isq::power(1 * si::watt)); static_assert(isq::pressure(10 * Ba) == isq::pressure(1 * si::pascal)); -static_assert(isq::dynamic_viscosity(10 * P) == isq::dynamic_viscosity(1 * (si::pascal * si::second))); -static_assert(isq::kinematic_viscosity(10'000 * St) == isq::kinematic_viscosity(1 * (square(si::metre) / si::second))); -static_assert(isq::wavenumber(1 * K) == isq::wavenumber(100 * (1 / si::metre))); +static_assert(isq::dynamic_viscosity(10 * P) == isq::dynamic_viscosity(1 * si::pascal * si::second)); +static_assert(isq::kinematic_viscosity(10'000 * St) == isq::kinematic_viscosity(1 * square(si::metre) / si::second)); +static_assert(isq::wavenumber(1 * K) == isq::wavenumber(100 / si::metre)); static_assert(10'000'000 * erg + 1 * si::joule == 2 * si::joule); static_assert(1 * si::joule + 10'000'000 * erg == 2 * si::joule); static_assert(is_of_type<10'000'000 * erg + 1 * si::joule, quantity>); static_assert(is_of_type<1 * si::joule + 10'000'000 * erg, quantity>); -static_assert(1 * K + 100 * (1 / si::metre) == 2 * K); -static_assert(100 * (1 / si::metre) + 1 * K == 2 * K); -static_assert(is_of_type<1 * K + 100 * (1 / si::metre), quantity<1 / si::metre, int>>); -static_assert(is_of_type<100 * (1 / si::metre) + 1 * K, quantity<1 / si::metre, int>>); +static_assert(1 * K + 100 / si::metre == 2 * K); +static_assert(100 / si::metre + 1 * K == 2 * K); +static_assert(is_of_type<1 * K + 100 / si::metre, quantity>); +static_assert(is_of_type<100 / si::metre + 1 * K, quantity>); } // namespace diff --git a/test/unit_test/static/chrono_test.cpp b/test/unit_test/static/chrono_test.cpp index 3b4059bb9..b8c61fa53 100644 --- a/test/unit_test/static/chrono_test.cpp +++ b/test/unit_test/static/chrono_test.cpp @@ -114,7 +114,7 @@ static_assert(quantity{std::chrono::years{1}} == 31556952 * s); // operators static_assert(quantity{1s} + 1 * s == 2 * s); static_assert(quantity{1s} + 1 * min == 61 * s); -static_assert(10 * m / quantity{2s} == 5 * (m / s)); +static_assert(10 * m / quantity{2s} == 5 * m / s); static_assert(quantity_point{sys_seconds{1s}} + 1 * s == chrono_point_origin + 2 * s); static_assert(quantity_point{sys_seconds{1s}} + 1 * min == chrono_point_origin + 61 * s); diff --git a/test/unit_test/static/concepts_test.cpp b/test/unit_test/static/concepts_test.cpp index 21c6cbcc5..b63228b08 100644 --- a/test/unit_test/static/concepts_test.cpp +++ b/test/unit_test/static/concepts_test.cpp @@ -48,7 +48,7 @@ struct dim_speed : decltype(isq::dim_length / isq::dim_time) {}; // BaseDimension static_assert(detail::BaseDimension); static_assert(!detail::BaseDimension>); -static_assert(!detail::BaseDimension>); +static_assert(!detail::BaseDimension>); static_assert(!detail::BaseDimension(isq::dim_length))>>); static_assert(!detail::BaseDimension>>); static_assert(!detail::BaseDimension); @@ -58,7 +58,7 @@ static_assert(!detail::BaseDimension); // DerivedDimension static_assert(detail::DerivedDimension>); -static_assert(detail::DerivedDimension>); +static_assert(detail::DerivedDimension>); static_assert(detail::DerivedDimension(isq::dim_length))>>); static_assert(detail::DerivedDimension>>); static_assert(detail::DerivedDimension); @@ -70,7 +70,7 @@ static_assert(!detail::DerivedDimension); // Dimension static_assert(Dimension); static_assert(Dimension>); -static_assert(Dimension>); +static_assert(Dimension>); static_assert(Dimension(isq::dim_length))>>); static_assert(Dimension>>); static_assert(Dimension); @@ -137,7 +137,7 @@ static_assert(Unit); static_assert(Unit)>>); static_assert(Unit); static_assert(Unit>); -static_assert(Unit>); +static_assert(Unit>); static_assert(Unit * si::second)>>); static_assert(Unit>); static_assert(Unit(si::metre))>>); @@ -161,7 +161,7 @@ static_assert(detail::NamedUnit); static_assert(!detail::NamedUnit); static_assert(!detail::NamedUnit)>>); static_assert(!detail::NamedUnit>); -static_assert(!detail::NamedUnit>); +static_assert(!detail::NamedUnit>); static_assert(!detail::NamedUnit * si::second)>>); static_assert(!detail::NamedUnit>); static_assert(!detail::NamedUnit(si::metre))>>); @@ -185,7 +185,7 @@ static_assert(PrefixableUnit); static_assert(!PrefixableUnit); static_assert(!PrefixableUnit)>>); static_assert(!PrefixableUnit>); -static_assert(!PrefixableUnit>); +static_assert(!PrefixableUnit>); static_assert(!PrefixableUnit * si::second)>>); static_assert(!PrefixableUnit>); static_assert(!PrefixableUnit(si::metre))>>); @@ -209,7 +209,7 @@ static_assert(!AssociatedUnit); static_assert(AssociatedUnit); static_assert(AssociatedUnit)>>); static_assert(AssociatedUnit>); -static_assert(AssociatedUnit>); +static_assert(AssociatedUnit>); static_assert(AssociatedUnit * si::second)>>); static_assert(AssociatedUnit>); static_assert(AssociatedUnit(si::metre))>>); @@ -232,7 +232,7 @@ static_assert(UnitOf); static_assert(UnitOf); static_assert(UnitOf); static_assert(UnitOf); -static_assert(UnitOf); +static_assert(UnitOf); static_assert(UnitOf); static_assert(UnitOf); static_assert(UnitOf); diff --git a/test/unit_test/static/dimension_test.cpp b/test/unit_test/static/dimension_test.cpp index d5091f54c..0ceed4f62 100644 --- a/test/unit_test/static/dimension_test.cpp +++ b/test/unit_test/static/dimension_test.cpp @@ -41,8 +41,8 @@ inline constexpr struct time_ : base_dimension<"T"> {} time; QUANTITY_SPEC_(q_time, time); inline constexpr struct second_ : named_unit<"s", kind_of> {} second; -inline constexpr auto frequency = 1 / time; -inline constexpr auto action = 1 / time; +inline constexpr auto frequency = inverse(time); +inline constexpr auto action = inverse(time); inline constexpr auto area = length * length; inline constexpr auto volume = area * length; inline constexpr auto speed = length / time; @@ -71,13 +71,13 @@ static_assert(detail::DerivedDimension); // dimensio static_assert(detail::BaseDimension); // length // derived dimension expression template syntax verification -static_assert(is_of_type<1 / time, derived_dimension>>); -static_assert(is_of_type<1 / (1 / time), time_>); +static_assert(is_of_type>>); +static_assert(is_of_type); static_assert(is_of_type); static_assert(is_of_type