fix: pow() fixed for quantity specs and units

This commit is contained in:
Mateusz Pusz
2023-06-13 09:14:01 +03:00
parent 211bd61895
commit de4fefde3f
2 changed files with 23 additions and 11 deletions

View File

@@ -545,9 +545,9 @@ template<std::intmax_t Num, std::intmax_t Den = 1, QuantitySpec Q>
// `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<Q>)
return detail::clone_kind_of<Q{}>(

View File

@@ -501,6 +501,16 @@ template<typename... Expr1, typename... Expr2>
canonical_lhs.mag == canonical_rhs.mag;
}
namespace detail {
template<typename T>
inline constexpr bool is_specialization_of_derived_unit = false;
template<typename... Expr>
inline constexpr bool is_specialization_of_derived_unit<derived_unit<Expr...>> = true;
} // namespace detail
/**
* @brief Computes the value of a unit raised to the `Num/Den` power
*
@@ -514,16 +524,18 @@ template<std::intmax_t Num, std::intmax_t Den = 1, Unit U>
requires detail::non_zero<Den>
[[nodiscard]] consteval Unit auto pow(U u)
{
if constexpr (requires { U::symbol; }) {
if constexpr (Den == 1)
return derived_unit<power<U, Num>>{};
else
return derived_unit<power<U, Num, Den>>{};
} else if constexpr (detail::is_specialization_of_scaled_unit<U>) {
if constexpr (Num == 0 || is_same_v<U, struct one>)
return one;
else if constexpr (ratio{Num, Den} == 1)
return u;
else if constexpr (detail::is_specialization_of_scaled_unit<U>)
return scaled_unit<pow<Num, Den>(U::mag), std::remove_const_t<decltype(pow<Num, Den>(U::reference_unit))>>{};
} else {
else if constexpr (detail::is_specialization_of_derived_unit<U>)
return detail::expr_pow<Num, Den, derived_unit, struct one, detail::type_list_of_unit_less>(u);
}
else if constexpr (Den == 1)
return derived_unit<power<U, Num>>{};
else
return derived_unit<power<U, Num, Den>>{};
}
/**