Address review feedback

This commit is contained in:
Chip Hogg
2022-04-19 15:42:43 +00:00
parent 94fe48dd64
commit 2b37bc7b3e
5 changed files with 47 additions and 29 deletions

View File

@@ -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;

View File

@@ -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)));
}
/**

View File

@@ -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);

View File

@@ -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

View File

@@ -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 ==