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.
|
// Magnitude product implementation.
|
||||||
|
|
||||||
@@ -569,18 +581,14 @@ constexpr auto common_magnitude(magnitude<H1, T1...> m1, magnitude<H2, T2...> m2
|
|||||||
{
|
{
|
||||||
using detail::remove_positive_power;
|
using detail::remove_positive_power;
|
||||||
|
|
||||||
// Case for when H1 has the smaller base.
|
|
||||||
if constexpr (H1.get_base() < H2.get_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);
|
return remove_positive_power(magnitude<H1>{}) * common_magnitude(magnitude<T1...>{}, m2);
|
||||||
}
|
} else if constexpr (H2.get_base() < H1.get_base()) {
|
||||||
|
// When H2 has the smaller base, prepend to result from recursion.
|
||||||
// Case for when H2 has the smaller base.
|
|
||||||
if constexpr (H2.get_base() < H1.get_base()) {
|
|
||||||
return remove_positive_power(magnitude<H2>{}) * common_magnitude(m1, magnitude<T2...>{});
|
return remove_positive_power(magnitude<H2>{}) * common_magnitude(m1, magnitude<T2...>{});
|
||||||
}
|
} else {
|
||||||
|
// When the bases are equal, pick whichever has the lower power.
|
||||||
// Case for equal bases.
|
|
||||||
if constexpr (H1.get_base() == H2.get_base()) {
|
|
||||||
constexpr auto common_tail = common_magnitude(magnitude<T1...>{}, magnitude<T2...>{});
|
constexpr auto common_tail = common_magnitude(magnitude<T1...>{}, magnitude<T2...>{});
|
||||||
if constexpr (H1.power < H2.power) {
|
if constexpr (H1.power < H2.power) {
|
||||||
return magnitude<H1>{} * common_tail;
|
return magnitude<H1>{} * common_tail;
|
||||||
|
@@ -62,10 +62,7 @@ inline constexpr Magnitude auto quantity_magnitude<quantity<D, U, Rep>> = [] {
|
|||||||
}();
|
}();
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline constexpr ratio quantity_ratio = std::enable_if_t<!Quantity<T>>{};
|
inline constexpr ratio quantity_ratio = as_ratio(quantity_magnitude<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>>);
|
|
||||||
|
|
||||||
template<typename QFrom, typename QTo>
|
template<typename QFrom, typename QTo>
|
||||||
inline constexpr Magnitude auto cast_magnitude = [] {
|
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 traits = detail::cast_traits<Rep, typename To::rep>;
|
||||||
using ratio_type = TYPENAME traits::ratio_type;
|
using ratio_type = TYPENAME traits::ratio_type;
|
||||||
using rep_type = TYPENAME traits::rep_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>) {
|
constexpr Magnitude auto c_mag = detail::cast_magnitude<quantity<D, U, Rep>, To>;
|
||||||
return To(
|
constexpr Magnitude auto num = numerator(c_mag);
|
||||||
static_cast<TYPENAME To::rep>(static_cast<rep_type>(q.number()) * (get_value<ratio_type>(numerator(c_mag)) /
|
constexpr Magnitude auto den = denominator(c_mag);
|
||||||
get_value<ratio_type>(denominator(c_mag)))));
|
constexpr Magnitude auto irr = c_mag * (den / num);
|
||||||
} else {
|
|
||||||
return To(
|
constexpr auto val = [](Magnitude auto m) { return get_value<ratio_type>(m); };
|
||||||
static_cast<TYPENAME To::rep>(static_cast<rep_type>(q.number()) * get_value<ratio_type>(numerator(c_mag)) /
|
return To(static_cast<TYPENAME To::rep>(static_cast<rep_type>(q.number()) * val(num) / val(den) * val(irr)));
|
||||||
get_value<ratio_type>(denominator(c_mag))));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -61,6 +61,8 @@ struct ratio {
|
|||||||
|
|
||||||
[[nodiscard]] friend constexpr bool operator==(const ratio&, const ratio&) = default;
|
[[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-(const ratio& r) { return ratio(-r.num, r.den, r.exp); }
|
||||||
|
|
||||||
[[nodiscard]] friend constexpr ratio operator+(ratio lhs, ratio rhs)
|
[[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 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)
|
[[nodiscard]] friend constexpr ratio operator*(const ratio& lhs, const ratio& rhs)
|
||||||
{
|
{
|
||||||
const std::intmax_t gcd1 = std::gcd(lhs.num, rhs.den);
|
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, 4)) == 4);
|
||||||
static_assert(denominator(ratio(3, 7, -2)) == 700);
|
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
|
} // namespace
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
#include <units/isq/si/pressure.h>
|
#include <units/isq/si/pressure.h>
|
||||||
#include <units/isq/si/speed.h>
|
#include <units/isq/si/speed.h>
|
||||||
#include <units/isq/si/time.h>
|
#include <units/isq/si/time.h>
|
||||||
|
#include <units/math.h>
|
||||||
|
|
||||||
namespace {
|
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_plus_si_literals
|
||||||
|
|
||||||
namespace fps_test {
|
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::literals;
|
||||||
using namespace units::isq::si::fps::references;
|
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(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(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) ==
|
static_assert(is_near(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
|
si::length<si::metre>(2),
|
||||||
static_assert(si::length<si::metre>(1) + quantity_cast<si::length<si::metre>>(1. * ft / 0.3048) ==
|
si::length<si::femtometre>(1))); // 1 m in ft + 1 m
|
||||||
si::length<si::metre>(2)); // 1 m + 1 m in ft
|
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)) ==
|
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
|
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 ==
|
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