refactor: 💥 ratio hidden as an implementation detail behind mag_ratio
This commit is contained in:
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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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{}>(
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in new issue
Block a user