Skip to content

Commit ae6b5ec

Browse files
committed
Replace MP_UNITS_CONSTEVAL with constexpr in unit operations
Changes MP_UNITS_CONSTEVAL to constexpr for unit multiplication, division, and inverse operations in unit.h. This allows these functions to be used in runtime contexts, which is necessary for DSP applications where unit calculations may depend on runtime parameters. Specifically fixes compilation error with clang (and likely other compilers?) where consteval functions cannot be called in non-constant contexts, such as: ```c++ m_frequency = inverse<si::hertz>(period); ``` Added runtime tests for `inverse()` function covering time-to-frequency conversion, runtime parameters, and unit conversion.
1 parent a6a5b61 commit ae6b5ec

2 files changed

Lines changed: 32 additions & 5 deletions

File tree

src/core/include/mp-units/framework/unit.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ struct unit_interface {
147147
* Multiplication by `1` returns the same unit, otherwise `scaled_unit` is being returned.
148148
*/
149149
template<UnitMagnitude M, Unit U>
150-
[[nodiscard]] friend MP_UNITS_CONSTEVAL Unit auto operator*(M, U u)
150+
[[nodiscard]] friend constexpr Unit auto operator*(M, U u)
151151
{
152152
if constexpr (std::is_same_v<M, MP_UNITS_NONCONST_TYPE(mp_units::mag<1>)>)
153153
return u;
@@ -171,7 +171,7 @@ struct unit_interface {
171171
* Returns the result of multiplication with an inverse unit.
172172
*/
173173
template<UnitMagnitude M, Unit U>
174-
[[nodiscard]] friend MP_UNITS_CONSTEVAL Unit auto operator/(M mag, U u)
174+
[[nodiscard]] friend constexpr Unit auto operator/(M mag, U u)
175175
{
176176
return mag * inverse(u);
177177
}
@@ -182,7 +182,7 @@ struct unit_interface {
182182
* to the derived unit and the magnitude remains outside forming another scaled unit as a result of the operation.
183183
*/
184184
template<Unit Lhs, Unit Rhs>
185-
[[nodiscard]] friend MP_UNITS_CONSTEVAL Unit auto operator*(Lhs lhs, Rhs rhs)
185+
[[nodiscard]] friend constexpr Unit auto operator*(Lhs lhs, Rhs rhs)
186186
{
187187
return expr_multiply<derived_unit, struct one>(lhs, rhs);
188188
}
@@ -193,7 +193,7 @@ struct unit_interface {
193193
* to the derived unit and the magnitude remains outside forming another scaled unit as a result of the operation.
194194
*/
195195
template<Unit Lhs, Unit Rhs>
196-
[[nodiscard]] friend MP_UNITS_CONSTEVAL Unit auto operator/(Lhs lhs, Rhs rhs)
196+
[[nodiscard]] friend constexpr Unit auto operator/(Lhs lhs, Rhs rhs)
197197
{
198198
return expr_divide<derived_unit, struct one>(lhs, rhs);
199199
}
@@ -593,7 +593,7 @@ template<Unit T, typename... Expr>
593593

594594
MP_UNITS_EXPORT_BEGIN
595595

596-
[[nodiscard]] MP_UNITS_CONSTEVAL Unit auto inverse(Unit auto u) { return one / u; }
596+
[[nodiscard]] constexpr Unit auto inverse(Unit auto u) { return one / u; }
597597

598598
/**
599599
* @brief Computes the value of a unit raised to the `Num/Den` power

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)