Skip to content

Commit 1bfe034

Browse files
authored
Merge pull request #726 from rothmichaels/fix/optimal-inverse-runtime
fix: enable runtime usage of inverse function by using compile-time unit extraction
2 parents a03edb9 + 4ca7dae commit 1bfe034

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

src/core/include/mp-units/math.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -413,13 +413,15 @@ template<Unit auto To, auto R, typename Rep>
413413
}
414414
{
415415
#if MP_UNITS_API_NATURAL_UNITS
416-
if constexpr (!MP_UNITS_ASSOCIATED_UNIT<MP_UNITS_REMOVE_CONST(decltype(To))>)
417-
return (representation_values<Rep>::one() * one).force_in(To * q.unit) / q;
418-
else
416+
if constexpr (!MP_UNITS_ASSOCIATED_UNIT<MP_UNITS_REMOVE_CONST(decltype(To))>) {
417+
constexpr Unit auto unit = To * quantity<R, Rep>::unit;
418+
return (representation_values<Rep>::one() * one).force_in(unit) / q;
419+
} else
419420
#endif
420421
{
421422
constexpr QuantitySpec auto qs = get_quantity_spec(To) * quantity<R, Rep>::quantity_spec;
422-
return qs(representation_values<Rep>::one() * one).force_in(To * q.unit) / q;
423+
constexpr Unit auto unit = To * quantity<R, Rep>::unit;
424+
return qs(representation_values<Rep>::one() * one).force_in(unit) / q;
423425
}
424426
}
425427

test/runtime/math_test.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,4 +589,31 @@ TEST_CASE("math operations", "[math]")
589589
REQUIRE_THAT(atan2(1. * isq::length[km], 1000. * isq::length[m]), AlmostEquals(45. * angle[deg]));
590590
}
591591
}
592+
593+
SECTION("inverse functions")
594+
{
595+
SECTION("inverse of time quantity returns frequency")
596+
{
597+
auto period = 2.0 * isq::time[s];
598+
auto frequency = inverse<si::hertz>(period);
599+
REQUIRE(frequency == 0.5 * isq::frequency[Hz]);
600+
}
601+
602+
SECTION("inverse works with runtime values")
603+
{
604+
// Test the specific case that fails with consteval
605+
double runtime_value = 3.0;
606+
auto period = runtime_value * isq::time[s];
607+
auto frequency = inverse<si::hertz>(period);
608+
auto expected = (1.0 / 3.0) * isq::frequency[Hz];
609+
REQUIRE_THAT(frequency, AlmostEquals(expected));
610+
}
611+
612+
SECTION("inverse with different input units")
613+
{
614+
auto period_ms = 500.0 * isq::time[ms];
615+
auto frequency = inverse<si::hertz>(period_ms);
616+
REQUIRE(frequency == 2.0 * isq::frequency[Hz]);
617+
}
618+
}
592619
}

0 commit comments

Comments
 (0)