diff --git a/src/utility/include/mp-units/math.h b/src/utility/include/mp-units/math.h index 7bdf71893..29254672e 100644 --- a/src/utility/include/mp-units/math.h +++ b/src/utility/include/mp-units/math.h @@ -271,6 +271,19 @@ template } } +/** + * @brief Computes the inverse of a quantity in a provided unit + */ +template +[[nodiscard]] constexpr QuantityOf auto inverse(const quantity& q) + requires requires { + quantity_values::one(); + value_cast(1 / q); + } +{ + return (quantity_values::one() * one).force_in(To * q.unit) / q; +} + /** * @brief Computes the square root of the sum of the squares of x and y, * without undue overflow or underflow at intermediate stages of the computation diff --git a/test/unit_test/static/math_test.cpp b/test/unit_test/static/math_test.cpp index a8b23053a..980f68e08 100644 --- a/test/unit_test/static/math_test.cpp +++ b/test/unit_test/static/math_test.cpp @@ -26,8 +26,6 @@ #include #include -#if __cpp_lib_constexpr_cmath || MP_UNITS_COMP_GCC - namespace { using namespace mp_units; @@ -40,6 +38,8 @@ template return is_same_v && v1 == v2 && (... && (v1 == vs)); } +#if __cpp_lib_constexpr_cmath || MP_UNITS_COMP_GCC + static_assert(compare(pow<0>(2 * m), 1 * one)); static_assert(compare(pow<1>(2 * m), 2 * m)); static_assert(compare(pow<2>(2 * m), 4 * pow<2>(m), 4 * m2)); @@ -201,6 +201,20 @@ static_assert(compare(round(-1499. * isq::time[ms]), -1. * isq::time static_assert(compare(round(-1500. * isq::time[ms]), -2. * isq::time[s])); static_assert(compare(round(-1999. * isq::time[ms]), -2. * isq::time[s])); -} // namespace - #endif + +// non-truncating +static_assert(compare(inverse(250 * Hz), 4000 * us)); +static_assert(compare(inverse(250 * kHz), 4 * us)); +static_assert(compare(inverse(250 * uHz), 4 * ks)); + +// truncating +static_assert(compare(inverse(1 * kHz), 0 * s)); + +// floating-point representation does not truncate +static_assert(compare(inverse(1. * kHz), 0.001 * s)); + +// check if constraints work properly for a derived unit of a narrowed kind +static_assert(compare(inverse(1 * s), 1 * Hz)); + +} // namespace