Replace make_ratio with as_magnitude<ratio>

It's cleaner to just have the one way.
This commit is contained in:
Chip Hogg
2022-01-08 17:29:40 -05:00
parent ef6f937460
commit 0a470f2617
2 changed files with 31 additions and 36 deletions

View File

@@ -170,19 +170,13 @@ concept Magnitude = detail::is_magnitude<T>::value;
/** /**
* @brief Convert any positive integer to a Magnitude. * @brief Convert any positive integer to a Magnitude.
*/
template<std::integral auto N>
requires requires { N > 0; }
constexpr Magnitude auto as_magnitude();
/**
* @brief Make a Magnitude that is a rational number.
* *
* This will be the main way end users create Magnitudes. They should rarely (if ever) create a magnitude<...> by * This will be the main way end users create Magnitudes. They should rarely (if ever) create a magnitude<...> by
* manually adding base powers. * manually adding base powers.
*/ */
template<std::intmax_t N, std::intmax_t D = 1> template<ratio R>
constexpr auto make_ratio() { return as_magnitude<N>() / as_magnitude<D>(); } requires requires { R.num > 0; }
constexpr Magnitude auto as_magnitude();
/** /**
* @brief A base to represent pi. * @brief A base to represent pi.
@@ -358,8 +352,10 @@ constexpr auto operator/(Magnitude auto l, Magnitude auto r) { return l * invers
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// `as_magnitude()` implementation. // `as_magnitude()` implementation.
template<std::integral auto N> template<ratio R>
requires requires { N > 0; } requires requires { R.num > 0; }
constexpr Magnitude auto as_magnitude() { return detail::prime_factorization_v<N>; } constexpr Magnitude auto as_magnitude() {
return detail::prime_factorization_v<R.num> / detail::prime_factorization_v<R.den>;
}
} // namespace units::mag } // namespace units::mag

View File

@@ -32,18 +32,17 @@ TEST_CASE("make_ratio performs prime factorization correctly")
{ {
SECTION("Performs prime factorization when denominator is 1") SECTION("Performs prime factorization when denominator is 1")
{ {
CHECK(make_ratio<1>() == magnitude<>{}); CHECK(as_magnitude<1>() == magnitude<>{});
CHECK(make_ratio<2>() == magnitude<base_power{2}>{}); CHECK(as_magnitude<2>() == magnitude<base_power{2}>{});
CHECK(make_ratio<3>() == magnitude<base_power{3}>{}); CHECK(as_magnitude<3>() == magnitude<base_power{3}>{});
CHECK(make_ratio<4>() == magnitude<base_power{2, 2}>{}); CHECK(as_magnitude<4>() == magnitude<base_power{2, 2}>{});
CHECK(make_ratio<792>() == magnitude<base_power{2, 3}, base_power{3, 2}, base_power{11}>{}); CHECK(as_magnitude<792>() == magnitude<base_power{2, 3}, base_power{3, 2}, base_power{11}>{});
} }
SECTION("Reduces fractions to lowest terms") SECTION("Supports fractions")
{ {
CHECK(make_ratio<8, 8>() == magnitude<>{}); CHECK(as_magnitude<ratio{5, 8}>() == magnitude<base_power{2, -3}, base_power{5}>{});
CHECK(make_ratio<50, 80>() == magnitude<base_power{2, -3}, base_power{5}>{});
} }
} }
@@ -51,20 +50,20 @@ TEST_CASE("Equality works for magnitudes")
{ {
SECTION("Equivalent ratios are equal") SECTION("Equivalent ratios are equal")
{ {
CHECK(make_ratio<1>() == make_ratio<1>()); CHECK(as_magnitude<1>() == as_magnitude<1>());
CHECK(make_ratio<3>() == make_ratio<3>()); CHECK(as_magnitude<3>() == as_magnitude<3>());
CHECK(make_ratio<3, 4>() == make_ratio<9, 12>()); CHECK(as_magnitude<ratio{3, 4}>() == as_magnitude<ratio{9, 12}>());
} }
SECTION("Different ratios are unequal") SECTION("Different ratios are unequal")
{ {
CHECK(make_ratio<3>() != make_ratio<5>()); CHECK(as_magnitude<3>() != as_magnitude<5>());
CHECK(make_ratio<3>() != make_ratio<3, 2>()); CHECK(as_magnitude<3>() != as_magnitude<ratio{3, 2}>());
} }
SECTION("Supports constexpr") SECTION("Supports constexpr")
{ {
constexpr auto eq = (make_ratio<4, 5>() == make_ratio<4, 3>()); constexpr auto eq = (as_magnitude<ratio{4, 5}>() == as_magnitude<ratio{4, 3}>());
CHECK(!eq); CHECK(!eq);
} }
} }
@@ -73,25 +72,25 @@ TEST_CASE("Multiplication works for magnitudes")
{ {
SECTION("Reciprocals reduce to null magnitude") SECTION("Reciprocals reduce to null magnitude")
{ {
CHECK(make_ratio<3, 4>() * make_ratio<4, 3>() == make_ratio<1>()); CHECK(as_magnitude<ratio{3, 4}>() * as_magnitude<ratio{4, 3}>() == as_magnitude<1>());
} }
SECTION("Products work as expected") SECTION("Products work as expected")
{ {
CHECK(make_ratio<4, 5>() * make_ratio<4, 3>() == make_ratio<16, 15>()); CHECK(as_magnitude<ratio{4, 5}>() * as_magnitude<ratio{4, 3}>() == as_magnitude<ratio{16, 15}>());
} }
SECTION("Products handle pi correctly") SECTION("Products handle pi correctly")
{ {
CHECK( CHECK(
pi_to_the<1>() * make_ratio<2, 3>() * pi_to_the<ratio{-1, 2}>() == pi_to_the<1>() * as_magnitude<ratio{2, 3}>() * pi_to_the<ratio{-1, 2}>() ==
magnitude<base_power{2}, base_power{3, -1}, base_power<pi_base>{ratio{1, 2}}>{}); magnitude<base_power{2}, base_power{3, -1}, base_power<pi_base>{ratio{1, 2}}>{});
} }
SECTION("Supports constexpr") SECTION("Supports constexpr")
{ {
constexpr auto p = make_ratio<4, 5>() * make_ratio<4, 3>(); constexpr auto p = as_magnitude<ratio{4, 5}>() * as_magnitude<ratio{4, 3}>();
CHECK(p == make_ratio<16, 15>()); CHECK(p == as_magnitude<ratio{16, 15}>());
} }
} }
@@ -99,19 +98,19 @@ TEST_CASE("Division works for magnitudes")
{ {
SECTION("Dividing anything by itself reduces to null magnitude") SECTION("Dividing anything by itself reduces to null magnitude")
{ {
CHECK(make_ratio<3, 4>() / make_ratio<3, 4>() == make_ratio<1>()); CHECK(as_magnitude<ratio{3, 4}>() / as_magnitude<ratio{3, 4}>() == as_magnitude<1>());
CHECK(make_ratio<15>() / make_ratio<15>() == make_ratio<1>()); CHECK(as_magnitude<15>() / as_magnitude<15>() == as_magnitude<1>());
} }
SECTION("Quotients work as expected") SECTION("Quotients work as expected")
{ {
CHECK(make_ratio<4, 5>() / make_ratio<4, 3>() == make_ratio<3, 5>()); CHECK(as_magnitude<ratio{4, 5}>() / as_magnitude<ratio{4, 3}>() == as_magnitude<ratio{3, 5}>());
} }
SECTION("Supports constexpr") SECTION("Supports constexpr")
{ {
constexpr auto q = make_ratio<4, 5>() / make_ratio<4, 3>(); constexpr auto q = as_magnitude<ratio{4, 5}>() / as_magnitude<ratio{4, 3}>();
CHECK(q == make_ratio<3, 5>()); CHECK(q == as_magnitude<ratio{3, 5}>());
} }
} }