forked from mpusz/mp-units
Address review feedback
This commit is contained in:
@@ -427,6 +427,18 @@ constexpr auto pow(magnitude<BPs...>)
|
||||
}
|
||||
}
|
||||
|
||||
template<BasePower auto... BPs>
|
||||
constexpr auto sqrt(magnitude<BPs...> m)
|
||||
{
|
||||
return pow<ratio{1, 2}>(m);
|
||||
}
|
||||
|
||||
template<BasePower auto... BPs>
|
||||
constexpr auto cbrt(magnitude<BPs...> m)
|
||||
{
|
||||
return pow<ratio{1, 3}>(m);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Magnitude product implementation.
|
||||
|
||||
@@ -569,18 +581,14 @@ constexpr auto common_magnitude(magnitude<H1, T1...> m1, magnitude<H2, T2...> m2
|
||||
{
|
||||
using detail::remove_positive_power;
|
||||
|
||||
// Case for when H1 has the smaller base.
|
||||
if constexpr (H1.get_base() < H2.get_base()) {
|
||||
// When H1 has the smaller base, prepend to result from recursion.
|
||||
return remove_positive_power(magnitude<H1>{}) * common_magnitude(magnitude<T1...>{}, m2);
|
||||
}
|
||||
|
||||
// Case for when H2 has the smaller base.
|
||||
if constexpr (H2.get_base() < H1.get_base()) {
|
||||
} else if constexpr (H2.get_base() < H1.get_base()) {
|
||||
// When H2 has the smaller base, prepend to result from recursion.
|
||||
return remove_positive_power(magnitude<H2>{}) * common_magnitude(m1, magnitude<T2...>{});
|
||||
}
|
||||
|
||||
// Case for equal bases.
|
||||
if constexpr (H1.get_base() == H2.get_base()) {
|
||||
} else {
|
||||
// When the bases are equal, pick whichever has the lower power.
|
||||
constexpr auto common_tail = common_magnitude(magnitude<T1...>{}, magnitude<T2...>{});
|
||||
if constexpr (H1.power < H2.power) {
|
||||
return magnitude<H1>{} * common_tail;
|
||||
|
@@ -62,10 +62,7 @@ inline constexpr Magnitude auto quantity_magnitude<quantity<D, U, Rep>> = [] {
|
||||
}();
|
||||
|
||||
template<typename T>
|
||||
inline constexpr ratio quantity_ratio = std::enable_if_t<!Quantity<T>>{};
|
||||
|
||||
template<typename D, typename U, typename Rep>
|
||||
inline constexpr ratio quantity_ratio<quantity<D, U, Rep>> = as_ratio(quantity_magnitude<quantity<D, U, Rep>>);
|
||||
inline constexpr ratio quantity_ratio = as_ratio(quantity_magnitude<T>);
|
||||
|
||||
template<typename QFrom, typename QTo>
|
||||
inline constexpr Magnitude auto cast_magnitude = [] {
|
||||
@@ -119,17 +116,14 @@ template<Quantity To, typename D, typename U, scalable_with_<typename To::rep> R
|
||||
using traits = detail::cast_traits<Rep, typename To::rep>;
|
||||
using ratio_type = TYPENAME traits::ratio_type;
|
||||
using rep_type = TYPENAME traits::rep_type;
|
||||
constexpr Magnitude auto c_mag = detail::cast_magnitude<quantity<D, U, Rep>, To>;
|
||||
|
||||
if constexpr (treat_as_floating_point<rep_type>) {
|
||||
return To(
|
||||
static_cast<TYPENAME To::rep>(static_cast<rep_type>(q.number()) * (get_value<ratio_type>(numerator(c_mag)) /
|
||||
get_value<ratio_type>(denominator(c_mag)))));
|
||||
} else {
|
||||
return To(
|
||||
static_cast<TYPENAME To::rep>(static_cast<rep_type>(q.number()) * get_value<ratio_type>(numerator(c_mag)) /
|
||||
get_value<ratio_type>(denominator(c_mag))));
|
||||
}
|
||||
constexpr Magnitude auto c_mag = detail::cast_magnitude<quantity<D, U, Rep>, To>;
|
||||
constexpr Magnitude auto num = numerator(c_mag);
|
||||
constexpr Magnitude auto den = denominator(c_mag);
|
||||
constexpr Magnitude auto irr = c_mag * (den / num);
|
||||
|
||||
constexpr auto val = [](Magnitude auto m) { return get_value<ratio_type>(m); };
|
||||
return To(static_cast<TYPENAME To::rep>(static_cast<rep_type>(q.number()) * val(num) / val(den) * val(irr)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -61,6 +61,8 @@ struct ratio {
|
||||
|
||||
[[nodiscard]] friend constexpr bool operator==(const ratio&, const ratio&) = default;
|
||||
|
||||
[[nodiscard]] friend constexpr auto operator<=>(const ratio& lhs, const ratio& rhs) { return (lhs - rhs).num <=> 0; }
|
||||
|
||||
[[nodiscard]] friend constexpr ratio operator-(const ratio& r) { return ratio(-r.num, r.den, r.exp); }
|
||||
|
||||
[[nodiscard]] friend constexpr ratio operator+(ratio lhs, ratio rhs)
|
||||
@@ -81,8 +83,6 @@ struct ratio {
|
||||
|
||||
[[nodiscard]] friend constexpr ratio operator-(const ratio& lhs, const ratio& rhs) { return lhs + (-rhs); }
|
||||
|
||||
[[nodiscard]] friend constexpr auto operator<=>(const ratio& lhs, const ratio& rhs) { return (lhs - rhs).num <=> 0; }
|
||||
|
||||
[[nodiscard]] friend constexpr ratio operator*(const ratio& lhs, const ratio& rhs)
|
||||
{
|
||||
const std::intmax_t gcd1 = std::gcd(lhs.num, rhs.den);
|
||||
|
@@ -108,4 +108,10 @@ static_assert(numerator(ratio(3, 7, 2)) == 300);
|
||||
static_assert(denominator(ratio(3, 4)) == 4);
|
||||
static_assert(denominator(ratio(3, 7, -2)) == 700);
|
||||
|
||||
// comparison
|
||||
static_assert((ratio(3, 4) <=> ratio(6, 8)) == (0 <=> 0));
|
||||
static_assert((ratio(3, 4) <=> ratio(-3, 4)) == (0 <=> -1));
|
||||
static_assert((ratio(-3, 4) <=> ratio(3, -4)) == (0 <=> 0));
|
||||
static_assert((ratio(1, 1, 1) <=> ratio(10)) == (0 <=> 0));
|
||||
|
||||
} // namespace
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include <units/isq/si/pressure.h>
|
||||
#include <units/isq/si/speed.h>
|
||||
#include <units/isq/si/time.h>
|
||||
#include <units/math.h>
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -113,6 +114,13 @@ static_assert(1_q_pdl_per_ft2 > 1.4881639435_q_Pa && 1_q_pdl_per_ft2 < 1.4881639
|
||||
} // namespace fps_plus_si_literals
|
||||
|
||||
namespace fps_test {
|
||||
namespace {
|
||||
constexpr bool is_near(auto a, auto b, auto tol)
|
||||
{
|
||||
const auto diff = a - b;
|
||||
return (diff <= tol) && (-diff <= tol);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
using namespace units::isq::si::fps::literals;
|
||||
using namespace units::isq::si::fps::references;
|
||||
@@ -121,10 +129,12 @@ using namespace units::isq::si::fps::references;
|
||||
|
||||
static_assert(si::length<si::metre>(1) + 1 * ft == si::length<si::metre>(1.3048));
|
||||
static_assert(1 * ft + si::length<si::metre>(1) == si::length<si::metre>(1.3048));
|
||||
static_assert(quantity_cast<si::length<si::metre>>(1. * ft / 0.3048) + si::length<si::metre>(1) ==
|
||||
si::length<si::metre>(2)); // 1 m in ft + 1 m
|
||||
static_assert(si::length<si::metre>(1) + quantity_cast<si::length<si::metre>>(1. * ft / 0.3048) ==
|
||||
si::length<si::metre>(2)); // 1 m + 1 m in ft
|
||||
static_assert(is_near(quantity_cast<si::length<si::metre>>(1. * ft / 0.3048) + si::length<si::metre>(1),
|
||||
si::length<si::metre>(2),
|
||||
si::length<si::femtometre>(1))); // 1 m in ft + 1 m
|
||||
static_assert(is_near(si::length<si::metre>(1) + quantity_cast<si::length<si::metre>>(1. * ft / 0.3048),
|
||||
si::length<si::metre>(2),
|
||||
si::length<si::femtometre>(1))); // 1 m + 1 m in ft
|
||||
static_assert(1 * ft + quantity_cast<si::fps::length<si::fps::foot>>(si::length<si::metre>(0.3048)) ==
|
||||
2 * ft); // 1 ft + 1 ft in m
|
||||
static_assert(quantity_cast<si::fps::length<si::fps::foot>>(si::length<si::metre>(0.3048)) + 1 * ft ==
|
||||
|
Reference in New Issue
Block a user