diff --git a/src/utility/include/mp-units/math.h b/src/utility/include/mp-units/math.h index 04b4b494..389068f7 100644 --- a/src/utility/include/mp-units/math.h +++ b/src/utility/include/mp-units/math.h @@ -51,11 +51,12 @@ namespace mp_units { * @return Quantity The result of computation */ template - requires detail::non_zero && - requires { quantity_values::one(); } - [[nodiscard]] constexpr quantity(R), Rep> pow(const quantity& q) noexcept - requires requires { pow(q.numerical_value_ref_in(q.unit), 1.0); } || - requires { std::pow(q.numerical_value_ref_in(q.unit), 1.0); } + requires detail::non_zero && requires(Rep v) { + quantity_values::one(); + requires requires { pow(v, 1.0); } || requires { std::pow(v, 1.0); }; + } +[[nodiscard]] constexpr quantity(R), Rep> pow(const quantity& q) noexcept + { if constexpr (Num == 0) { return quantity(R), Rep>::one(); @@ -78,9 +79,8 @@ template * @return Quantity The result of computation */ template + requires requires(Rep v) { sqrt(v); } || requires(Rep v) { std::sqrt(v); } [[nodiscard]] constexpr quantity sqrt(const quantity& q) noexcept - requires requires { sqrt(q.numerical_value_ref_in(q.unit)); } || - requires { std::sqrt(q.numerical_value_ref_in(q.unit)); } { using std::sqrt; return {static_cast(sqrt(q.numerical_value_ref_in(q.unit))), sqrt(R)}; @@ -95,9 +95,8 @@ template * @return Quantity The result of computation */ template + requires requires(Rep v) { cbrt(v); } || requires(Rep v) { std::cbrt(v); } [[nodiscard]] constexpr quantity cbrt(const quantity& q) noexcept - requires requires { cbrt(q.numerical_value_ref_in(q.unit)); } || - requires { std::cbrt(q.numerical_value_ref_in(q.unit)); } { using std::cbrt; return {static_cast(cbrt(q.numerical_value_ref_in(q.unit))), cbrt(R)}; @@ -112,9 +111,8 @@ template * @return Quantity The value of the same quantity type */ template auto R, typename Rep> + requires requires(Rep v) { exp(v); } || requires(Rep v) { std::exp(v); } [[nodiscard]] constexpr quantity exp(const quantity& q) - requires requires { exp(q.numerical_value_ref_in(q.unit)); } || - requires { std::exp(q.numerical_value_ref_in(q.unit)); } { using std::exp; return value_cast( @@ -128,9 +126,8 @@ template auto R, typename Rep> * @return Quantity The absolute value of a provided quantity */ template + requires requires(Rep v) { abs(v); } || requires(Rep v) { std::abs(v); } [[nodiscard]] constexpr quantity abs(const quantity& q) noexcept - requires requires { abs(q.numerical_value_ref_in(q.unit)); } || - requires { std::abs(q.numerical_value_ref_in(q.unit)); } { using std::abs; return {static_cast(abs(q.numerical_value_ref_in(q.unit))), R}; @@ -143,10 +140,8 @@ template * @return bool: Whether the number is finite or not. */ template + requires requires(Rep v) { isfinite(v); } || requires(Rep v) { std::isfinite(v); } [[nodiscard]] constexpr bool isfinite(const quantity& a) noexcept - requires( - requires { isfinite(a.numerical_value_ref_in(a.unit)); } || - requires { std::isfinite(a.numerical_value_ref_in(a.unit)); }) { using std::isfinite; return isfinite(a.numerical_value_ref_in(a.unit)); @@ -159,9 +154,8 @@ template * @return bool: Whether the number is infinite or not. */ template + requires requires(Rep v) { isinf(v); } || requires(Rep v) { std::isinf(v); } [[nodiscard]] constexpr bool isinf(const quantity& a) noexcept - requires( - requires { isinf(a.numerical_value_ref_in(a.unit)); } || requires { std::isinf(a.numerical_value_ref_in(a.unit)); }) { using std::isinf; return isinf(a.numerical_value_ref_in(a.unit)); @@ -175,9 +169,8 @@ template * @return bool: Whether the number is a NaN or not. */ template + requires requires(Rep v) { isnan(v); } || requires(Rep v) { std::isnan(v); } [[nodiscard]] constexpr bool isnan(const quantity& a) noexcept - requires( - requires { isnan(a.numerical_value_ref_in(a.unit)); } || requires { std::isnan(a.numerical_value_ref_in(a.unit)); }) { using std::isnan; return isnan(a.numerical_value_ref_in(a.unit)); @@ -192,20 +185,14 @@ template * @return Quantity: The nearest floating point representable to ax+b */ template -[[nodiscard]] constexpr QuantityOf auto -fma(const quantity& a, const quantity& x, const quantity& b) noexcept requires requires { common_quantity_spec(get_quantity_spec(R) * get_quantity_spec(S), get_quantity_spec(T)); } && - (get_unit(R) * get_unit(S) == get_unit(T)) && - ( - requires { - fma(a.numerical_value_ref_in(a.unit), x.numerical_value_ref_in(x.unit), - b.numerical_value_ref_in(b.unit)); - } || - requires { - std::fma(a.numerical_value_ref_in(a.unit), x.numerical_value_ref_in(x.unit), - b.numerical_value_ref_in(b.unit)); - }) + (get_unit(R) * get_unit(S) == get_unit(T)) && requires(Rep1 v1, Rep2 v2, Rep3 v3) { + requires requires { fma(v1, v2, v3); } || requires { std::fma(v1, v2, v3); }; + } +[[nodiscard]] constexpr QuantityOf auto fma(const quantity& a, + const quantity& x, + const quantity& b) noexcept { using std::fma; return quantity{ @@ -237,8 +224,7 @@ template */ template [[nodiscard]] constexpr quantity(R), Rep> floor(const quantity& q) noexcept - requires((!treat_as_floating_point) || requires { floor(q.numerical_value_ref_in(q.unit)); } || - requires { std::floor(q.numerical_value_ref_in(q.unit)); }) && + requires((!treat_as_floating_point) || requires(Rep v) { floor(v); } || requires(Rep v) { std::floor(v); }) && (To == get_unit(R) || requires { q.force_in(To); quantity_values::one(); @@ -275,8 +261,7 @@ template */ template [[nodiscard]] constexpr quantity(R), Rep> ceil(const quantity& q) noexcept - requires((!treat_as_floating_point) || requires { ceil(q.numerical_value_ref_in(q.unit)); } || - requires { std::ceil(q.numerical_value_ref_in(q.unit)); }) && + requires((!treat_as_floating_point) || requires(Rep v) { ceil(v); } || requires(Rep v) { std::ceil(v); }) && (To == get_unit(R) || requires { q.force_in(To); quantity_values::one(); @@ -315,8 +300,7 @@ template */ template [[nodiscard]] constexpr quantity(R), Rep> round(const quantity& q) noexcept - requires((!treat_as_floating_point) || requires { round(q.numerical_value_ref_in(q.unit)); } || - requires { std::round(q.numerical_value_ref_in(q.unit)); }) && + requires((!treat_as_floating_point) || requires(Rep v) { round(v); } || requires(Rep v) { std::round(v); }) && (To == get_unit(R) || requires { ::mp_units::floor(q); quantity_values::one(); @@ -365,12 +349,12 @@ template * without undue overflow or underflow at intermediate stages of the computation */ template + requires requires(Rep1 v1, Rep2 v2) { + common_reference(R1, R2); + requires requires { hypot(v1, v2); } || requires { std::hypot(v1, v2); }; + } [[nodiscard]] constexpr QuantityOf auto hypot( const quantity& x, const quantity& y) noexcept - requires requires { common_reference(R1, R2); } && - ( - requires { hypot(x.numerical_value_ref_in(x.unit), y.numerical_value_ref_in(y.unit)); } || - requires { std::hypot(x.numerical_value_ref_in(x.unit), y.numerical_value_ref_in(y.unit)); }) { constexpr auto ref = common_reference(R1, R2); constexpr auto unit = get_unit(ref); @@ -383,18 +367,12 @@ template * without undue overflow or underflow at intermediate stages of the computation */ template + requires requires(Rep1 v1, Rep2 v2, Rep3 v3) { + common_reference(R1, R2, R3); + requires requires { hypot(v1, v2, v3); } || requires { std::hypot(v1, v2, v3); }; + } [[nodiscard]] constexpr QuantityOf auto hypot( const quantity& x, const quantity& y, const quantity& z) noexcept - requires requires { common_reference(R1, R2, R3); } && - ( - requires { - hypot(x.numerical_value_ref_in(x.unit), y.numerical_value_ref_in(y.unit), - z.numerical_value_ref_in(z.unit)); - } || - requires { - std::hypot(x.numerical_value_ref_in(x.unit), y.numerical_value_ref_in(y.unit), - z.numerical_value_ref_in(z.unit)); - }) { constexpr auto ref = common_reference(R1, R2); constexpr auto unit = get_unit(ref); @@ -405,9 +383,8 @@ template namespace isq { template auto R, typename Rep> + requires requires(Rep v) { sin(v); } || requires(Rep v) { std::sin(v); } [[nodiscard]] inline QuantityOf auto sin(const quantity& q) noexcept - requires requires { sin(q.numerical_value_ref_in(q.unit)); } || - requires { std::sin(q.numerical_value_ref_in(q.unit)); } { using std::sin; if constexpr (!treat_as_floating_point) { @@ -420,9 +397,8 @@ template auto R, typename Rep> } template auto R, typename Rep> + requires requires(Rep v) { cos(v); } || requires(Rep v) { std::cos(v); } [[nodiscard]] inline QuantityOf auto cos(const quantity& q) noexcept - requires requires { cos(q.numerical_value_ref_in(q.unit)); } || - requires { std::cos(q.numerical_value_ref_in(q.unit)); } { using std::cos; if constexpr (!treat_as_floating_point) { @@ -435,9 +411,8 @@ template auto R, typename Rep> } template auto R, typename Rep> + requires requires(Rep v) { tan(v); } || requires(Rep v) { std::tan(v); } [[nodiscard]] inline QuantityOf auto tan(const quantity& q) noexcept - requires requires { tan(q.numerical_value_ref_in(q.unit)); } || - requires { std::tan(q.numerical_value_ref_in(q.unit)); } { using std::tan; if constexpr (!treat_as_floating_point) { @@ -450,9 +425,8 @@ template auto R, typename Rep> } template auto R, typename Rep> + requires requires(Rep v) { asin(v); } || requires(Rep v) { std::asin(v); } [[nodiscard]] inline QuantityOf auto asin(const quantity& q) noexcept - requires requires { asin(q.numerical_value_ref_in(q.unit)); } || - requires { std::asin(q.numerical_value_ref_in(q.unit)); } { using std::asin; if constexpr (!treat_as_floating_point) { @@ -465,9 +439,8 @@ template auto R, typename Rep> } template auto R, typename Rep> + requires requires(Rep v) { acos(v); } || requires(Rep v) { std::acos(v); } [[nodiscard]] inline QuantityOf auto acos(const quantity& q) noexcept - requires requires { acos(q.numerical_value_ref_in(q.unit)); } || - requires { std::acos(q.numerical_value_ref_in(q.unit)); } { using std::acos; if constexpr (!treat_as_floating_point) { @@ -480,9 +453,8 @@ template auto R, typename Rep> } template auto R, typename Rep> + requires requires(Rep v) { atan(v); } || requires(Rep v) { std::atan(v); } [[nodiscard]] inline QuantityOf auto atan(const quantity& q) noexcept - requires requires { atan(q.numerical_value_ref_in(q.unit)); } || - requires { std::atan(q.numerical_value_ref_in(q.unit)); } { using std::atan; if constexpr (!treat_as_floating_point) { @@ -499,9 +471,8 @@ template auto R, typename Rep> namespace angular { template auto R, typename Rep> + requires requires(Rep v) { sin(v); } || requires(Rep v) { std::sin(v); } [[nodiscard]] inline QuantityOf auto sin(const quantity& q) noexcept - requires requires { sin(q.numerical_value_ref_in(q.unit)); } || - requires { std::sin(q.numerical_value_ref_in(q.unit)); } { using std::sin; if constexpr (!treat_as_floating_point) { @@ -514,9 +485,8 @@ template auto R, typename Rep> } template auto R, typename Rep> + requires requires(Rep v) { cos(v); } || requires(Rep v) { std::cos(v); } [[nodiscard]] inline QuantityOf auto cos(const quantity& q) noexcept - requires requires { cos(q.numerical_value_ref_in(q.unit)); } || - requires { std::cos(q.numerical_value_ref_in(q.unit)); } { using std::cos; if constexpr (!treat_as_floating_point) { @@ -529,9 +499,8 @@ template auto R, typename Rep> } template auto R, typename Rep> + requires requires(Rep v) { tan(v); } || requires(Rep v) { std::tan(v); } [[nodiscard]] inline QuantityOf auto tan(const quantity& q) noexcept - requires requires { tan(q.numerical_value_ref_in(q.unit)); } || - requires { std::tan(q.numerical_value_ref_in(q.unit)); } { using std::tan; if constexpr (!treat_as_floating_point) { @@ -544,9 +513,8 @@ template auto R, typename Rep> } template auto R, typename Rep> + requires requires(Rep v) { asin(v); } || requires(Rep v) { std::asin(v); } [[nodiscard]] inline QuantityOf auto asin(const quantity& q) noexcept - requires requires { asin(q.numerical_value_ref_in(q.unit)); } || - requires { std::asin(q.numerical_value_ref_in(q.unit)); } { using std::asin; if constexpr (!treat_as_floating_point) { @@ -559,9 +527,8 @@ template auto R, typename Rep> } template auto R, typename Rep> + requires requires(Rep v) { acos(v); } || requires(Rep v) { std::acos(v); } [[nodiscard]] inline QuantityOf auto acos(const quantity& q) noexcept - requires requires { acos(q.numerical_value_ref_in(q.unit)); } || - requires { std::acos(q.numerical_value_ref_in(q.unit)); } { using std::acos; if constexpr (!treat_as_floating_point) { @@ -574,9 +541,8 @@ template auto R, typename Rep> } template auto R, typename Rep> + requires requires(Rep v) { atan(v); } || requires(Rep v) { std::atan(v); } [[nodiscard]] inline QuantityOf auto atan(const quantity& q) noexcept - requires requires { atan(q.numerical_value_ref_in(q.unit)); } || - requires { std::atan(q.numerical_value_ref_in(q.unit)); } { using std::atan; if constexpr (!treat_as_floating_point) {