From de4fefde3f93980fa00d980874922597aaba3f43 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 13 Jun 2023 09:14:01 +0300 Subject: [PATCH] fix: `pow()` fixed for quantity specs and units --- src/core/include/mp-units/quantity_spec.h | 6 ++--- src/core/include/mp-units/unit.h | 28 ++++++++++++++++------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/core/include/mp-units/quantity_spec.h b/src/core/include/mp-units/quantity_spec.h index d3029c92..4412c099 100644 --- a/src/core/include/mp-units/quantity_spec.h +++ b/src/core/include/mp-units/quantity_spec.h @@ -545,9 +545,9 @@ template // `2 * one * (2 * one)` should compare to `4 * one` // `2 * rad * (2 * rad)` should compare to `4 * rad^2` // all are dimensionless quantities :-( - if constexpr (q == dimensionless) - return q; - else if constexpr (Num == 1 && Den == 1) + if constexpr (Num == 0 || q == dimensionless) + return dimensionless; + else if constexpr (ratio{Num, Den} == 1) return q; else if constexpr (detail::IntermediateDerivedQuantitySpec) return detail::clone_kind_of( diff --git a/src/core/include/mp-units/unit.h b/src/core/include/mp-units/unit.h index 12257032..76d9d815 100644 --- a/src/core/include/mp-units/unit.h +++ b/src/core/include/mp-units/unit.h @@ -501,6 +501,16 @@ template canonical_lhs.mag == canonical_rhs.mag; } +namespace detail { + +template +inline constexpr bool is_specialization_of_derived_unit = false; + +template +inline constexpr bool is_specialization_of_derived_unit> = true; + +} // namespace detail + /** * @brief Computes the value of a unit raised to the `Num/Den` power * @@ -514,16 +524,18 @@ template requires detail::non_zero [[nodiscard]] consteval Unit auto pow(U u) { - if constexpr (requires { U::symbol; }) { - if constexpr (Den == 1) - return derived_unit>{}; - else - return derived_unit>{}; - } else if constexpr (detail::is_specialization_of_scaled_unit) { + if constexpr (Num == 0 || is_same_v) + return one; + else if constexpr (ratio{Num, Den} == 1) + return u; + else if constexpr (detail::is_specialization_of_scaled_unit) return scaled_unit(U::mag), std::remove_const_t(U::reference_unit))>>{}; - } else { + else if constexpr (detail::is_specialization_of_derived_unit) return detail::expr_pow(u); - } + else if constexpr (Den == 1) + return derived_unit>{}; + else + return derived_unit>{}; } /**