From b61dafec57f376a8c2e8620f23da96b09bc429c3 Mon Sep 17 00:00:00 2001 From: Justin Kottinger Date: Fri, 21 Feb 2025 10:36:43 -0700 Subject: [PATCH 1/5] Unit-Safe Implementation of --- au/code/au/math.hh | 19 +++++++++++++++ au/code/au/math_test.cc | 54 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/au/code/au/math.hh b/au/code/au/math.hh index 90d61dfc..dc2762d5 100644 --- a/au/code/au/math.hh +++ b/au/code/au/math.hh @@ -33,6 +33,7 @@ using std::abs; using std::copysign; using std::cos; using std::fmod; +using std::hypot; using std::isnan; using std::max; using std::min; @@ -172,6 +173,24 @@ constexpr auto clamp(QuantityPoint v, return (v < lo) ? ResultT{lo} : (hi < v) ? ResultT{hi} : ResultT{v}; } +template +auto hypot(Quantity x, Quantity y) +{ + using U = CommonUnitT; + using R = std::common_type_t; + using ResultT = Quantity; + return make_quantity(std::hypot(x.in(U{}), y.in(U{}))); +} + +template +auto hypot(QuantityPoint x, QuantityPoint y) +{ + using U = CommonPointUnitT; + using R = std::common_type_t; + using ResultT = QuantityPoint; + return make_quantity_point(std::hypot(x.in(U{}), y.in(U{}))); +} + // Copysign where the magnitude has units. template constexpr auto copysign(Quantity mag, T sgn) { diff --git a/au/code/au/math_test.cc b/au/code/au/math_test.cc index 4c2c7f8a..d25d286d 100644 --- a/au/code/au/math_test.cc +++ b/au/code/au/math_test.cc @@ -159,6 +159,60 @@ TEST(clamp, SupportsZeroForMultipleArguments) { EXPECT_THAT(clamp(feet(6), ZERO, ZERO), SameTypeAndValue(feet(0))); } +TEST(hypot, QuantityConsistentWithStdHypotWhenTypesAreIdentical) { + auto expect_consistent_with_std_hypot = [](auto u, auto v) { + const auto expected = ohms(std::hypot(u, v)); + const auto actual = hypot(ohms(u), ohms(v)); + EXPECT_THAT(actual, SameTypeAndValue(expected)); + }; + + // Rep: `int`. + expect_consistent_with_std_hypot(-1, 0); + expect_consistent_with_std_hypot(0, 0); + expect_consistent_with_std_hypot(1, 0); + expect_consistent_with_std_hypot(2, 0); + expect_consistent_with_std_hypot(4, 2); + + // Rep: `double`. + expect_consistent_with_std_hypot(-1.0, 0.0); + expect_consistent_with_std_hypot(0.0, 0.0); + expect_consistent_with_std_hypot(1.0, 0.0); + expect_consistent_with_std_hypot(2.0, 0.0); + expect_consistent_with_std_hypot(4.0, 2.0); +} + +TEST(hypot, QuantityProducesResultsInCommonUnitOfInputs) { + EXPECT_THAT(hypot(centi(meters)(30), milli(meters)(400)), + SameTypeAndValue(milli(meters)(500.0))); +} + +TEST(hypot, QuantityPointConsistentWithStdHypotWhenTypesAreIdentical) { + auto expect_consistent_with_std_hypot = [](auto u, auto v) { + const auto expected = meters_pt(std::hypot(u, v)); + const auto actual = hypot(meters_pt(u), meters_pt(v)); + EXPECT_THAT(actual, SameTypeAndValue(expected)); + }; + + // Rep: `int`. + expect_consistent_with_std_hypot(-1, 0); + expect_consistent_with_std_hypot(0, 0); + expect_consistent_with_std_hypot(1, 0); + expect_consistent_with_std_hypot(2, 0); + expect_consistent_with_std_hypot(4, 2); + + // Rep: `double`. + expect_consistent_with_std_hypot(-1.0, 0.0); + expect_consistent_with_std_hypot(0.0, 0.0); + expect_consistent_with_std_hypot(1.0, 0.0); + expect_consistent_with_std_hypot(2.0, 0.0); + expect_consistent_with_std_hypot(4.0, 2.0); +} + +TEST(hypot, QuantityPointProducesResultsInCommonUnitOfInputs) { + EXPECT_THAT(hypot(centi(meters_pt)(30), milli(meters_pt)(400)), + SameTypeAndValue(milli(meters_pt)(500.0))); +} + TEST(copysign, ReturnsSameTypesAsStdCopysignForSameUnitInputs) { auto expect_consistent_with_std_copysign = [](auto mag, auto raw_sgn) { for (const auto test_sgn : {-1, 0, +1}) { From b3987028f72a036258a3ace27898eb92cea1cc9c Mon Sep 17 00:00:00 2001 From: Justin Kottinger <168748737+justin-kottinger@users.noreply.github.com> Date: Fri, 21 Feb 2025 16:56:34 -0700 Subject: [PATCH 2/5] Update au/code/au/math_test.cc Co-authored-by: Chip Hogg --- au/code/au/math_test.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/au/code/au/math_test.cc b/au/code/au/math_test.cc index d25d286d..b90b89ed 100644 --- a/au/code/au/math_test.cc +++ b/au/code/au/math_test.cc @@ -184,6 +184,8 @@ TEST(hypot, QuantityConsistentWithStdHypotWhenTypesAreIdentical) { TEST(hypot, QuantityProducesResultsInCommonUnitOfInputs) { EXPECT_THAT(hypot(centi(meters)(30), milli(meters)(400)), SameTypeAndValue(milli(meters)(500.0))); + + EXPECT_THAT(hypot(inches(5.f), feet(1.f)), SameTypeAndValue(inches(13.f))); } TEST(hypot, QuantityPointConsistentWithStdHypotWhenTypesAreIdentical) { From 9400cc47e82c905efcf1e1f29b896deacf336366 Mon Sep 17 00:00:00 2001 From: Justin Kottinger Date: Mon, 24 Feb 2025 09:32:15 -0700 Subject: [PATCH 3/5] removed QuantityPoint implementation of au::hypot --- au/code/au/math.hh | 9 --------- au/code/au/math_test.cc | 27 --------------------------- 2 files changed, 36 deletions(-) diff --git a/au/code/au/math.hh b/au/code/au/math.hh index dc2762d5..b0055e87 100644 --- a/au/code/au/math.hh +++ b/au/code/au/math.hh @@ -182,15 +182,6 @@ auto hypot(Quantity x, Quantity y) return make_quantity(std::hypot(x.in(U{}), y.in(U{}))); } -template -auto hypot(QuantityPoint x, QuantityPoint y) -{ - using U = CommonPointUnitT; - using R = std::common_type_t; - using ResultT = QuantityPoint; - return make_quantity_point(std::hypot(x.in(U{}), y.in(U{}))); -} - // Copysign where the magnitude has units. template constexpr auto copysign(Quantity mag, T sgn) { diff --git a/au/code/au/math_test.cc b/au/code/au/math_test.cc index b90b89ed..dda4c821 100644 --- a/au/code/au/math_test.cc +++ b/au/code/au/math_test.cc @@ -188,33 +188,6 @@ TEST(hypot, QuantityProducesResultsInCommonUnitOfInputs) { EXPECT_THAT(hypot(inches(5.f), feet(1.f)), SameTypeAndValue(inches(13.f))); } -TEST(hypot, QuantityPointConsistentWithStdHypotWhenTypesAreIdentical) { - auto expect_consistent_with_std_hypot = [](auto u, auto v) { - const auto expected = meters_pt(std::hypot(u, v)); - const auto actual = hypot(meters_pt(u), meters_pt(v)); - EXPECT_THAT(actual, SameTypeAndValue(expected)); - }; - - // Rep: `int`. - expect_consistent_with_std_hypot(-1, 0); - expect_consistent_with_std_hypot(0, 0); - expect_consistent_with_std_hypot(1, 0); - expect_consistent_with_std_hypot(2, 0); - expect_consistent_with_std_hypot(4, 2); - - // Rep: `double`. - expect_consistent_with_std_hypot(-1.0, 0.0); - expect_consistent_with_std_hypot(0.0, 0.0); - expect_consistent_with_std_hypot(1.0, 0.0); - expect_consistent_with_std_hypot(2.0, 0.0); - expect_consistent_with_std_hypot(4.0, 2.0); -} - -TEST(hypot, QuantityPointProducesResultsInCommonUnitOfInputs) { - EXPECT_THAT(hypot(centi(meters_pt)(30), milli(meters_pt)(400)), - SameTypeAndValue(milli(meters_pt)(500.0))); -} - TEST(copysign, ReturnsSameTypesAsStdCopysignForSameUnitInputs) { auto expect_consistent_with_std_copysign = [](auto mag, auto raw_sgn) { for (const auto test_sgn : {-1, 0, +1}) { From 3659e121b288282f55b4365f5ea62f5c967ac22e Mon Sep 17 00:00:00 2001 From: Justin Kottinger <168748737+justin-kottinger@users.noreply.github.com> Date: Mon, 24 Feb 2025 09:40:46 -0700 Subject: [PATCH 4/5] Update au/code/au/math.hh Co-authored-by: Chip Hogg --- au/code/au/math.hh | 2 -- 1 file changed, 2 deletions(-) diff --git a/au/code/au/math.hh b/au/code/au/math.hh index b0055e87..96c0b0c8 100644 --- a/au/code/au/math.hh +++ b/au/code/au/math.hh @@ -177,8 +177,6 @@ template auto hypot(Quantity x, Quantity y) { using U = CommonUnitT; - using R = std::common_type_t; - using ResultT = Quantity; return make_quantity(std::hypot(x.in(U{}), y.in(U{}))); } From e8800b89b58261e3f20eef794f594d949d854da6 Mon Sep 17 00:00:00 2001 From: Justin Kottinger Date: Mon, 24 Feb 2025 09:42:29 -0700 Subject: [PATCH 5/5] moved curly brace to match clang formatting style --- au/code/au/math.hh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/au/code/au/math.hh b/au/code/au/math.hh index 96c0b0c8..671123e3 100644 --- a/au/code/au/math.hh +++ b/au/code/au/math.hh @@ -174,8 +174,7 @@ constexpr auto clamp(QuantityPoint v, } template -auto hypot(Quantity x, Quantity y) -{ +auto hypot(Quantity x, Quantity y) { using U = CommonUnitT; return make_quantity(std::hypot(x.in(U{}), y.in(U{}))); }