feat: power<Num, Den>() support added for dimensions and units
This commit is contained in:
1 parent
9bfe75ebf6
commit
e7bebac2a7
5 files changed
+124
-6
No files matched your search
@@ -112,13 +112,17 @@ inline constexpr bool is_specialization_of_power<power<F, Ints...>> = true;
|
||||
template<typename T, ratio R>
|
||||
consteval auto power_or_T_impl()
|
||||
{
|
||||
if constexpr (R.den == 1) {
|
||||
if constexpr (R.num == 1)
|
||||
return T{};
|
||||
else
|
||||
return power<T, R.num>{};
|
||||
if constexpr (is_specialization_of_power<T>) {
|
||||
return power_or_T_impl<typename T::factor, T::exponent * R>();
|
||||
} else {
|
||||
return power<T, R.num, R.den>{};
|
||||
if constexpr (R.den == 1) {
|
||||
if constexpr (R.num == 1)
|
||||
return T{};
|
||||
else
|
||||
return power<T, R.num>{};
|
||||
} else {
|
||||
return power<T, R.num, R.den>{};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -437,6 +441,32 @@ template<template<typename...> typename To, typename OneType, typename T>
|
||||
return To<OneType, per<T>>{};
|
||||
}
|
||||
|
||||
|
||||
template<std::intmax_t Num, std::intmax_t Den, template<typename...> typename To, typename OneType,
|
||||
template<typename, typename> typename Pred, typename... Nums, typename... Dens>
|
||||
requires detail::non_zero<Den>
|
||||
[[nodiscard]] consteval auto expr_pow_impl(type_list<Nums...>, type_list<Dens...>)
|
||||
{
|
||||
return detail::get_optimized_expression<type_list<power_or_T<Nums, ratio{Num, Den}>...>,
|
||||
type_list<power_or_T<Dens, ratio{Num, Den}>...>, OneType, Pred, To>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Computes the value of an expression raised to the `Num/Den` power
|
||||
*
|
||||
* @tparam Num Exponent numerator
|
||||
* @tparam Den Exponent denominator
|
||||
* @tparam T Expression being the base of the operation
|
||||
*/
|
||||
template<std::intmax_t Num, std::intmax_t Den, template<typename...> typename To, typename OneType,
|
||||
template<typename, typename> typename Pred, typename T>
|
||||
requires detail::non_zero<Den>
|
||||
[[nodiscard]] consteval auto expr_pow(T)
|
||||
{
|
||||
return expr_pow_impl<Num, Den, To, OneType, Pred>(typename T::_num_{}, typename T::_den_{});
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace units
|
||||
@@ -285,6 +285,28 @@ template<Dimension D1, Dimension D2>
|
||||
return std::derived_from<D1, D2> || std::derived_from<D2, D1>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Computes the value of a dimension raised to the `Num/Den` power
|
||||
*
|
||||
* @tparam Num Exponent numerator
|
||||
* @tparam Den Exponent denominator
|
||||
* @param d Dimension being the base of the operation
|
||||
*
|
||||
* @return Dimension The result of computation
|
||||
*/
|
||||
template<std::intmax_t Num, std::intmax_t Den = 1, Dimension D>
|
||||
requires detail::non_zero<Den>
|
||||
[[nodiscard]] consteval Dimension auto pow(D d)
|
||||
{
|
||||
if constexpr (BaseDimension<D>) {
|
||||
if constexpr (Den == 1)
|
||||
return derived_dimension<power<D, Num>>{};
|
||||
else
|
||||
return derived_dimension<power<D, Num, Den>>{};
|
||||
} else
|
||||
return detail::expr_pow<Num, Den, derived_dimension, struct one_dim, detail::type_list_of_base_dimension_less>(d);
|
||||
}
|
||||
|
||||
// TODO consider adding the support for text output of the dimensional equation
|
||||
|
||||
} // namespace units
|
||||
|
||||
@@ -471,6 +471,33 @@ template<Unit Lhs, Unit Rhs>
|
||||
return is_same_v<decltype(canonical_lhs.reference_unit), decltype(canonical_rhs.reference_unit)>;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Computes the value of a unit raised to the `Num/Den` power
|
||||
*
|
||||
* @tparam Num Exponent numerator
|
||||
* @tparam Den Exponent denominator
|
||||
* @param u Unit being the base of the operation
|
||||
*
|
||||
* @return Unit The result of computation
|
||||
*/
|
||||
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>) {
|
||||
return scaled_unit<pow<ratio{Num, Den}>(U::mag), std::remove_const_t<decltype(pow<Num, Den>(U::reference_unit))>>{};
|
||||
} else {
|
||||
return detail::expr_pow<Num, Den, derived_unit, struct one, detail::type_list_of_unit_less>(u);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Helper variable templates to create common powers
|
||||
template<Unit auto U>
|
||||
inline constexpr decltype(U * U) square;
|
||||
|
||||
Reference in new issue
Block a user