diff --git a/src/core/include/mp-units/framework/quantity_spec.h b/src/core/include/mp-units/framework/quantity_spec.h index d707f1c18..f27ef6ed0 100644 --- a/src/core/include/mp-units/framework/quantity_spec.h +++ b/src/core/include/mp-units/framework/quantity_spec.h @@ -965,7 +965,7 @@ template 0) { if constexpr (num_from_compl == max_compl) { constexpr auto res = explode_to_equation(NumFrom{}); - return convertible_impl( + return convertible( (res.equation * ... * map_power(NumsFrom{})) / (map_power(DenFrom{}) * ... * map_power(DensFrom{})), (map_power(NumTo{}) * ... * map_power(NumsTo{})) / (map_power(DenTo{}) * ... * map_power(DensTo{}))); } else if constexpr (den_from_compl == max_compl) { constexpr auto res = explode_to_equation(DenFrom{}); - return convertible_impl( + return convertible( (map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / (res.equation * ... * map_power(DensFrom{})), (map_power(NumTo{}) * ... * map_power(NumsTo{})) / (map_power(DenTo{}) * ... * map_power(DensTo{}))); } else if constexpr (num_to_compl == max_compl) { constexpr auto res = explode_to_equation(NumTo{}); - return min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / - (map_power(DenFrom{}) * ... * map_power(DensFrom{})), - (res.equation * ... * map_power(NumsTo{})) / - (map_power(DenTo{}) * ... * map_power(DensTo{})))); + return min(res.result, convertible((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / + (map_power(DenFrom{}) * ... * map_power(DensFrom{})), + (res.equation * ... * map_power(NumsTo{})) / + (map_power(DenTo{}) * ... * map_power(DensTo{})))); } else { constexpr auto res = explode_to_equation(DenTo{}); - return min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / - (map_power(DenFrom{}) * ... * map_power(DensFrom{})), - (map_power(NumTo{}) * ... * map_power(NumsTo{})) / - (res.equation * ... * map_power(DensTo{})))); + return min(res.result, convertible((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / + (map_power(DenFrom{}) * ... * map_power(DensFrom{})), + (map_power(NumTo{}) * ... * map_power(NumsTo{})) / + (res.equation * ... * map_power(DensTo{})))); } } } @@ -1043,19 +1043,19 @@ template 0) { if constexpr (den_from_compl == max_compl) { constexpr auto res = explode_to_equation(DenFrom{}); - return convertible_impl( + return convertible( dimensionless / (res.equation * ... * map_power(DensFrom{})), (map_power(NumTo{}) * ... * map_power(NumsTo{})) / (map_power(DenTo{}) * ... * map_power(DensTo{}))); } else if constexpr (num_to_compl == max_compl) { constexpr auto res = explode_to_equation(NumTo{}); - return min(res.result, convertible_impl(dimensionless / (map_power(DenFrom{}) * ... * map_power(DensFrom{})), - (res.equation * ... * map_power(NumsTo{})) / - (map_power(DenTo{}) * ... * map_power(DensTo{})))); + return min(res.result, convertible(dimensionless / (map_power(DenFrom{}) * ... * map_power(DensFrom{})), + (res.equation * ... * map_power(NumsTo{})) / + (map_power(DenTo{}) * ... * map_power(DensTo{})))); } else { constexpr auto res = explode_to_equation(DenTo{}); - return min(res.result, convertible_impl(dimensionless / (map_power(DenFrom{}) * ... * map_power(DensFrom{})), - (map_power(NumTo{}) * ... * map_power(NumsTo{})) / - (res.equation * ... * map_power(DensTo{})))); + return min(res.result, convertible(dimensionless / (map_power(DenFrom{}) * ... * map_power(DensFrom{})), + (map_power(NumTo{}) * ... * map_power(NumsTo{})) / + (res.equation * ... * map_power(DensTo{})))); } } } @@ -1081,19 +1081,19 @@ template 0) { if constexpr (num_from_compl == max_compl) { constexpr auto res = explode_to_equation(NumFrom{}); - return convertible_impl( + return convertible( (res.equation * ... * map_power(NumsFrom{})), (map_power(NumTo{}) * ... * map_power(NumsTo{})) / (map_power(DenTo{}) * ... * map_power(DensTo{}))); } else if constexpr (num_to_compl == max_compl) { constexpr auto res = explode_to_equation(NumTo{}); - return min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})), - (res.equation * ... * map_power(NumsTo{})) / - (map_power(DenTo{}) * ... * map_power(DensTo{})))); + return min(res.result, convertible((map_power(NumFrom{}) * ... * map_power(NumsFrom{})), + (res.equation * ... * map_power(NumsTo{})) / + (map_power(DenTo{}) * ... * map_power(DensTo{})))); } else { constexpr auto res = explode_to_equation(DenTo{}); - return min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})), - (map_power(NumTo{}) * ... * map_power(NumsTo{})) / - (res.equation * ... * map_power(DensTo{})))); + return min(res.result, convertible((map_power(NumFrom{}) * ... * map_power(NumsFrom{})), + (map_power(NumTo{}) * ... * map_power(NumsTo{})) / + (res.equation * ... * map_power(DensTo{})))); } } } @@ -1120,19 +1120,19 @@ template 0) { if constexpr (num_from_compl == max_compl) { constexpr auto res = explode_to_equation(NumFrom{}); - return convertible_impl( + return convertible( (res.equation * ... * map_power(NumsFrom{})) / (map_power(DenFrom{}) * ... * map_power(DensFrom{})), dimensionless / (map_power(DenTo{}) * ... * map_power(DensTo{}))); } else if constexpr (den_from_compl == max_compl) { constexpr auto res = explode_to_equation(DenFrom{}); - return convertible_impl( + return convertible( (map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / (res.equation * ... * map_power(DensFrom{})), dimensionless / (map_power(DenTo{}) * ... * map_power(DensTo{}))); } else { constexpr auto res = explode_to_equation(DenTo{}); - return min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / - (map_power(DenFrom{}) * ... * map_power(DensFrom{})), - dimensionless / (res.equation * ... * map_power(DensTo{})))); + return min(res.result, convertible((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / + (map_power(DenFrom{}) * ... * map_power(DensFrom{})), + dimensionless / (res.equation * ... * map_power(DensTo{})))); } } } @@ -1159,19 +1159,19 @@ template 0) { if constexpr (num_from_compl == max_compl) { constexpr auto res = explode_to_equation(NumFrom{}); - return convertible_impl( + return convertible( (res.equation * ... * map_power(NumsFrom{})) / (map_power(DenFrom{}) * ... * map_power(DensFrom{})), (map_power(NumTo{}) * ... * map_power(NumsTo{}))); } else if constexpr (den_from_compl == max_compl) { constexpr auto res = explode_to_equation(DenFrom{}); - return convertible_impl( + return convertible( (map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / (res.equation * ... * map_power(DensFrom{})), (map_power(NumTo{}) * ... * map_power(NumsTo{}))); } else { constexpr auto res = explode_to_equation(NumTo{}); - return min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / - (map_power(DenFrom{}) * ... * map_power(DensFrom{})), - (res.equation * ... * map_power(NumsTo{})))); + return min(res.result, convertible((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / + (map_power(DenFrom{}) * ... * map_power(DensFrom{})), + (res.equation * ... * map_power(NumsTo{})))); } } } @@ -1193,12 +1193,12 @@ template 0) { if constexpr (num_from_compl == max_compl) { constexpr auto res = explode_to_equation(NumFrom{}); - return convertible_impl((res.equation * ... * map_power(NumsFrom{})), - (map_power(NumTo{}) * ... * map_power(NumsTo{}))); + return convertible((res.equation * ... * map_power(NumsFrom{})), + (map_power(NumTo{}) * ... * map_power(NumsTo{}))); } else { constexpr auto res = explode_to_equation(NumTo{}); - return min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})), - (res.equation * ... * map_power(NumsTo{})))); + return min(res.result, convertible((map_power(NumFrom{}) * ... * map_power(NumsFrom{})), + (res.equation * ... * map_power(NumsTo{})))); } } } @@ -1220,12 +1220,12 @@ template 0) { if constexpr (den_from_compl == max_compl) { constexpr auto res = explode_to_equation(DenFrom{}); - return convertible_impl(dimensionless / (res.equation * ... * map_power(DensFrom{})), - dimensionless / (map_power(DenTo{}) * ... * map_power(DensTo{}))); + return convertible(dimensionless / (res.equation * ... * map_power(DensFrom{})), + dimensionless / (map_power(DenTo{}) * ... * map_power(DensTo{}))); } else { constexpr auto res = explode_to_equation(DenTo{}); - return min(res.result, convertible_impl(dimensionless / (map_power(DenFrom{}) * ... * map_power(DensFrom{})), - dimensionless / (res.equation * ... * map_power(DensTo{})))); + return min(res.result, convertible(dimensionless / (map_power(DenFrom{}) * ... * map_power(DensFrom{})), + dimensionless / (res.equation * ... * map_power(DensTo{})))); } } } @@ -1242,12 +1242,12 @@ template 0) { if constexpr (num_from_compl == max_compl) { constexpr auto res = explode_to_equation(NumFrom{}); - return convertible_impl((res.equation * ... * map_power(NumsFrom{})), - dimensionless / (map_power(DenTo{}) * ... * map_power(DensTo{}))); + return convertible((res.equation * ... * map_power(NumsFrom{})), + dimensionless / (map_power(DenTo{}) * ... * map_power(DensTo{}))); } else { constexpr auto res = explode_to_equation(DenTo{}); - return min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})), - dimensionless / (res.equation * ... * map_power(DensTo{})))); + return min(res.result, convertible((map_power(NumFrom{}) * ... * map_power(NumsFrom{})), + dimensionless / (res.equation * ... * map_power(DensTo{})))); } } } @@ -1263,12 +1263,12 @@ template 0) { if constexpr (den_from_compl == max_compl) { constexpr auto res = explode_to_equation(DenFrom{}); - return convertible_impl(dimensionless / (res.equation * ... * map_power(DensFrom{})), - (map_power(NumTo{}) * ... * map_power(NumsTo{}))); + return convertible(dimensionless / (res.equation * ... * map_power(DensFrom{})), + (map_power(NumTo{}) * ... * map_power(NumsTo{}))); } else { constexpr auto res = explode_to_equation(NumTo{}); - return min(res.result, convertible_impl(dimensionless / (map_power(DenFrom{}) * ... * map_power(DensFrom{})), - (res.equation * ... * map_power(NumsTo{})))); + return min(res.result, convertible(dimensionless / (map_power(DenFrom{}) * ... * map_power(DensFrom{})), + (res.equation * ... * map_power(NumsTo{})))); } } } @@ -1356,11 +1356,11 @@ template }; if constexpr ((NamedQuantitySpec && NamedQuantitySpec) || get_complexity(From{}) == get_complexity(To{})) - return exploded_kind_result(convertible_impl(from_kind, to_kind)); + return exploded_kind_result(convertible(from_kind, to_kind)); else if constexpr (get_complexity(From{}) > get_complexity(To{})) - return exploded_kind_result(convertible_impl(explode(from_kind).quantity, to_kind)); + return exploded_kind_result(convertible(explode(from_kind).quantity, to_kind)); else - return exploded_kind_result(convertible_impl(from_kind, explode(to_kind).quantity)); + return exploded_kind_result(convertible(from_kind, explode(to_kind).quantity)); } template @@ -1377,14 +1377,15 @@ template return no; else if constexpr (get_complexity(From{}) != get_complexity(To{})) { if constexpr (get_complexity(From{}) > get_complexity(To{})) - return convertible_impl(explode(from).quantity, to); + return convertible(explode(from).quantity, to); else { auto res = explode(to); - return min(res.result, convertible_impl(from, res.quantity)); + return min(res.result, convertible(from, res.quantity)); } } } + template [[nodiscard]] consteval specs_convertible_result convertible_impl(From from, To to) { @@ -1406,18 +1407,18 @@ template else if constexpr (DerivedQuantitySpec) { auto res = explode(from); if constexpr (NamedQuantitySpec) - return convertible_impl(res.quantity, to); + return convertible(res.quantity, to); else if constexpr (requires { to._equation_; }) { auto eq = explode_to_equation(to); - return min(eq.result, convertible_impl(res.quantity, eq.equation)); + return min(eq.result, convertible(res.quantity, eq.equation)); } else return are_ingredients_convertible(from, to); } else if constexpr (DerivedQuantitySpec) { auto res = explode(to); if constexpr (NamedQuantitySpec) - return min(res.result, convertible_impl(from, res.quantity)); + return min(res.result, convertible(from, res.quantity)); else if constexpr (requires { from._equation_; }) - return min(res.result, convertible_impl(from._equation_, res.quantity)); + return min(res.result, convertible(from._equation_, res.quantity)); else return min(res.result, are_ingredients_convertible(from, to)); } @@ -1425,6 +1426,15 @@ template return no; } +template +constexpr specs_convertible_result convertible_result = convertible_impl(From{}, To{}); + +template +[[nodiscard]] consteval specs_convertible_result convertible(From, To) +{ + return convertible_result; +} + } // namespace detail MP_UNITS_EXPORT_BEGIN @@ -1432,19 +1442,19 @@ MP_UNITS_EXPORT_BEGIN template [[nodiscard]] consteval bool implicitly_convertible(From from, To to) { - return detail::convertible_impl(from, to) == detail::specs_convertible_result::yes; + return detail::convertible(from, to) == detail::specs_convertible_result::yes; } template [[nodiscard]] consteval bool explicitly_convertible(From from, To to) { - return detail::convertible_impl(from, to) >= detail::specs_convertible_result::explicit_conversion; + return detail::convertible(from, to) >= detail::specs_convertible_result::explicit_conversion; } template [[nodiscard]] consteval bool castable(From from, To to) { - return detail::convertible_impl(from, to) >= detail::specs_convertible_result::cast; + return detail::convertible(from, to) >= detail::specs_convertible_result::cast; } template diff --git a/test/static/quantity_spec_test.cpp b/test/static/quantity_spec_test.cpp index 9db5c448a..f024ca5b5 100644 --- a/test/static/quantity_spec_test.cpp +++ b/test/static/quantity_spec_test.cpp @@ -506,291 +506,290 @@ static_assert(are_ingredients_convertible(dimensionless / area, dimensionless / // different dimensions -static_assert(convertible_impl(mass, length) == no); -static_assert(convertible_impl(speed, length) == no); -static_assert(convertible_impl(length, speed) == no); -static_assert(convertible_impl(energy, speed) == no); -static_assert(convertible_impl(length, kind_of