diff --git a/src/core/include/mp-units/quantity.h b/src/core/include/mp-units/quantity.h index 44c29bad..e845dcce 100644 --- a/src/core/include/mp-units/quantity.h +++ b/src/core/include/mp-units/quantity.h @@ -60,14 +60,21 @@ concept QuantityConvertibleTo = template concept InvokeResultOf = std::regular_invocable && RepresentationOf, Ch>; +template, + std::remove_const_t>::character> +concept InvocableQuantities = + Quantity && Quantity && InvokeResultOf; + template -concept InvocableQuantities = Quantity && Quantity && - InvokeResultOf && - requires { common_reference(Q1::reference, Q2::reference); }; +concept CommonlyInvocableQuantities = + Quantity && Quantity && (Q1::quantity_spec.character == Q2::quantity_spec.character) && requires { + common_reference(Q1::reference, Q2::reference); + } && InvocableQuantities; + template - requires detail::InvocableQuantities + requires detail::CommonlyInvocableQuantities using common_quantity_for = quantity>; @@ -403,7 +410,7 @@ explicit( // binary operators on quantities template - requires detail::InvocableQuantities, quantity, quantity> + requires detail::CommonlyInvocableQuantities, quantity, quantity> [[nodiscard]] constexpr Quantity auto operator+(const quantity& lhs, const quantity& rhs) { using ret = detail::common_quantity_for, quantity, quantity>; @@ -414,7 +421,7 @@ template } template - requires detail::InvocableQuantities, quantity, quantity> + requires detail::CommonlyInvocableQuantities, quantity, quantity> [[nodiscard]] constexpr Quantity auto operator-(const quantity& lhs, const quantity& rhs) { using ret = detail::common_quantity_for, quantity, quantity>; @@ -426,7 +433,7 @@ template template requires(!treat_as_floating_point) && (!treat_as_floating_point) && - detail::InvocableQuantities, quantity, quantity> + detail::CommonlyInvocableQuantities, quantity, quantity> [[nodiscard]] constexpr Quantity auto operator%(const quantity& lhs, const quantity& rhs) { gsl_ExpectsAudit(rhs != rhs.zero()); @@ -438,8 +445,7 @@ template } template - requires detail::InvokeResultOf<(get_quantity_spec(R1) * get_quantity_spec(R2)).character, std::multiplies<>, Rep1, - Rep2> + requires detail::InvocableQuantities, quantity, quantity> [[nodiscard]] constexpr Quantity auto operator*(const quantity& lhs, const quantity& rhs) { return make_quantity(lhs.numerical_value_ref_in(quantity::unit) * @@ -463,7 +469,7 @@ template } template - requires detail::InvokeResultOf<(get_quantity_spec(R1) / get_quantity_spec(R2)).character, std::divides<>, Rep1, Rep2> + requires detail::InvocableQuantities, quantity, quantity> [[nodiscard]] constexpr Quantity auto operator/(const quantity& lhs, const quantity& rhs) { gsl_ExpectsAudit(rhs != rhs.zero());