refactor: 💥 ratio hidden as an implementation detail behind mag_ratio

This commit is contained in:
Mateusz Pusz committed 2024-04-19 15:29:00 +01:00
1 parent ae1003b279
commit f90a218705
24 files changed
+126 -129

No files matched your search

@@ -99,7 +99,7 @@ template<typename F, int Num, int... Den>
requires(detail::valid_ratio<Num, Den...> && detail::positive_ratio<Num, Den...> && !detail::ratio_one<Num, Den...>)
struct power {
using factor = F;
static constexpr ratio exponent{Num, Den...};
static constexpr detail::ratio exponent{Num, Den...};
};
namespace detail {
+15 -15
View File
@@ -166,7 +166,7 @@ template<PowerVBase auto V, int Num, int... Den>
requires(detail::valid_ratio<Num, Den...> && !detail::ratio_one<Num, Den...>)
struct power_v {
static constexpr auto base = V;
static constexpr ratio exponent{Num, Den...};
static constexpr detail::ratio exponent{Num, Den...};
};
namespace detail {
@@ -565,7 +565,8 @@ template<std::intmax_t Num, std::intmax_t Den = 1, auto... Ms>
if constexpr (Num == 0) {
return magnitude<>{};
} else {
return magnitude<detail::power_v_or_T<detail::get_base(Ms), detail::get_exponent(Ms) * ratio{Num, Den}>()...>{};
return magnitude<
detail::power_v_or_T<detail::get_base(Ms), detail::get_exponent(Ms) * detail::ratio{Num, Den}>()...>{};
}
}
@@ -675,8 +676,6 @@ template<auto M>
}
}
} // namespace detail
template<auto... Ms>
[[nodiscard]] consteval auto numerator(magnitude<Ms...>)
{
@@ -685,8 +684,8 @@ template<auto... Ms>
[[nodiscard]] consteval auto denominator(Magnitude auto m) { return numerator(pow<-1>(m)); }
// Implementation of conversion to ratio goes here, because it needs `numerator()` and `denominator()`.
constexpr ratio as_ratio(Magnitude auto m)
// TODO This probably should not be exported but is used in chrono.h
MP_UNITS_EXPORT constexpr ratio as_ratio(Magnitude auto m)
requires(is_rational(decltype(m){}))
{
return ratio{
@@ -695,7 +694,6 @@ constexpr ratio as_ratio(Magnitude auto m)
};
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Common Magnitude.
//
@@ -714,8 +712,6 @@ constexpr ratio as_ratio(Magnitude auto m)
// Thus, we make the _simplest_ choice which reproduces the correct convention in the rational case: namely, taking the
// minimum power for each base (where absent bases implicitly have a power of 0).
namespace detail {
template<auto M>
[[nodiscard]] consteval auto remove_positive_power(magnitude<M> m)
{
@@ -830,16 +826,20 @@ inline constexpr auto prime_factorization_v = prime_factorization<N>::value;
* This will be the main way end users create Magnitudes. They should rarely (if ever) create a magnitude<...> by
* manually adding base powers.
*/
MP_UNITS_EXPORT template<ratio R>
requires detail::gt_zero<R.num>
inline constexpr Magnitude auto mag = detail::prime_factorization_v<R.num> / detail::prime_factorization_v<R.den>;
MP_UNITS_EXPORT template<std::intmax_t V>
requires detail::gt_zero<V>
inline constexpr Magnitude auto mag = detail::prime_factorization_v<V>;
MP_UNITS_EXPORT template<std::intmax_t N, std::intmax_t D>
requires detail::gt_zero<N>
inline constexpr Magnitude auto mag_ratio = detail::prime_factorization_v<N> / detail::prime_factorization_v<D>;
/**
* @brief Create a Magnitude which is some rational number raised to a rational power.
*/
MP_UNITS_EXPORT template<ratio Base, ratio Pow>
requires detail::gt_zero<Base.num>
inline constexpr Magnitude auto mag_power = pow<Pow.num, Pow.den>(mag<Base>);
MP_UNITS_EXPORT template<std::intmax_t Base, std::intmax_t Pow>
requires detail::gt_zero<Base>
inline constexpr Magnitude auto mag_power = pow<Pow>(mag<Base>);
namespace detail {
+3 -6
View File
@@ -32,9 +32,7 @@
#include <numeric>
#endif
namespace mp_units {
namespace detail {
namespace mp_units::detail {
template<typename T>
[[nodiscard]] MP_UNITS_CONSTEVAL T abs(T v) noexcept
@@ -59,14 +57,13 @@ template<typename T>
return lhs * rhs;
}
} // namespace detail
/**
* @brief Provides compile-time rational arithmetic support.
*
* This class is really similar to @c std::ratio. An important difference is the fact that the objects of that class
* are used as class NTTPs rather then a type template parameter kind.
*/
// TODO This probably should not be exported but is used in chrono.h
MP_UNITS_EXPORT struct ratio {
std::intmax_t num;
std::intmax_t den;
@@ -123,4 +120,4 @@ MP_UNITS_EXPORT struct ratio {
return ratio{num / gcd, den / gcd};
}
} // namespace mp_units
} // namespace mp_units::detail
+1 -1
View File
@@ -56,7 +56,7 @@ template<std::intmax_t Num, std::intmax_t Den = 1, auto R, typename Rep>
{
if constexpr (Num == 0) {
return quantity<pow<Num, Den>(R), Rep>::one();
} else if constexpr (ratio{Num, Den} == 1) {
} else if constexpr (Num == Den) {
return q;
} else {
using std::pow;
+1 -1
View File
@@ -555,7 +555,7 @@ template<std::intmax_t Num, std::intmax_t Den = 1, QuantitySpec Q>
// all are dimensionless quantities :-(
if constexpr (Num == 0 || Q{} == dimensionless)
return dimensionless;
else if constexpr (ratio{Num, Den} == 1)
else if constexpr (detail::ratio{Num, Den} == 1)
return q;
else if constexpr (detail::IntermediateDerivedQuantitySpec<Q>)
return detail::clone_kind_of<Q{}>(
+4 -4
View File
@@ -566,7 +566,7 @@ template<std::intmax_t Num, std::intmax_t Den = 1, Unit U>
{
if constexpr (Num == 0 || is_same_v<U, struct one>)
return one;
else if constexpr (ratio{Num, Den} == 1)
else if constexpr (detail::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))>>{};
@@ -617,9 +617,9 @@ template<std::intmax_t Num, std::intmax_t Den = 1, Unit U>
// common dimensionless units
// clang-format off
inline constexpr struct percent : named_unit<"%", mag<ratio{1, 100}> * one> {} percent;
inline constexpr struct per_mille : named_unit<symbol_text{u8"‰", "%o"}, mag<ratio(1, 1000)> * one> {} per_mille;
inline constexpr struct parts_per_million : named_unit<"ppm", mag<ratio(1, 1'000'000)> * one> {} parts_per_million;
inline constexpr struct percent : named_unit<"%", mag_ratio<1, 100> * one> {} percent;
inline constexpr struct per_mille : named_unit<symbol_text{u8"‰", "%o"}, mag_ratio<1, 1000> * one> {} per_mille;
inline constexpr struct parts_per_million : named_unit<"ppm", mag_ratio<1, 1'000'000> * one> {} parts_per_million;
inline constexpr auto ppm = parts_per_million;
// clang-format on