diff --git a/src/core/include/mp-units/bits/get_associated_quantity.h b/src/core/include/mp-units/bits/get_associated_quantity.h index d976b17e..1339ca0f 100644 --- a/src/core/include/mp-units/bits/get_associated_quantity.h +++ b/src/core/include/mp-units/bits/get_associated_quantity.h @@ -76,9 +76,9 @@ template template [[nodiscard]] consteval auto get_associated_quantity(U u) { - constexpr bool all_kinds = all_are_kinds(U{}); + constexpr bool all_kinds = all_are_kinds(MP_UNITS_IS_CONST_EXPR(u)); if constexpr (all_kinds) - return kind_of; + return kind_of; else return get_associated_quantity_impl(u); } diff --git a/src/core/include/mp-units/bits/hacks.h b/src/core/include/mp-units/bits/hacks.h index bbd3eec7..09a6daab 100644 --- a/src/core/include/mp-units/bits/hacks.h +++ b/src/core/include/mp-units/bits/hacks.h @@ -82,12 +82,14 @@ #define MP_UNITS_TYPENAME typename #define MP_UNITS_EXPRESSION(x) (x) #define MP_UNITS_IS_VALUE(x) (x) +#define MP_UNITS_IS_CONST_EXPR(x) decltype(x){} #else #define MP_UNITS_TYPENAME #define MP_UNITS_EXPRESSION(x) x -#define MP_UNITS_IS_VALUE(x) +#define MP_UNITS_IS_VALUE(x) x +#define MP_UNITS_IS_CONST_EXPR(x) x #endif diff --git a/src/core/include/mp-units/framework/quantity_spec.h b/src/core/include/mp-units/framework/quantity_spec.h index 51b497e0..af23ad74 100644 --- a/src/core/include/mp-units/framework/quantity_spec.h +++ b/src/core/include/mp-units/framework/quantity_spec.h @@ -673,9 +673,9 @@ template template [[nodiscard]] consteval bool ingredients_dimension_less(D1 lhs, D2 rhs) { - if constexpr (D1{} == D2{} || D1{} == dimension_one) + if constexpr (MP_UNITS_IS_CONST_EXPR(lhs) == MP_UNITS_IS_CONST_EXPR(rhs) || MP_UNITS_IS_CONST_EXPR(lhs) == dimension_one) return false; - else if constexpr (D2{} == dimension_one) + else if constexpr (MP_UNITS_IS_CONST_EXPR(rhs) == dimension_one) return true; else return detail::type_name() < detail::type_name(); @@ -1338,25 +1338,25 @@ template } template -[[nodiscard]] consteval specs_convertible_result convertible_kinds(From, To) +[[nodiscard]] consteval specs_convertible_result convertible_kinds(From from_kind, To to_kind) { constexpr auto exploded_kind_result = [](specs_convertible_result res) { using enum specs_convertible_result; return res == no ? no : yes; }; - if constexpr ((NamedQuantitySpec && NamedQuantitySpec) || - get_complexity(From{}) == get_complexity(To{})) - return convertible_impl(From{}, To{}); - else if constexpr (get_complexity(From{}) > get_complexity(To{})) + if constexpr ((NamedQuantitySpec && NamedQuantitySpec) || + get_complexity(MP_UNITS_IS_CONST_EXPR(from_kind)) == get_complexity(MP_UNITS_IS_CONST_EXPR(to_kind))) + return convertible_impl(MP_UNITS_IS_CONST_EXPR(from_kind), MP_UNITS_IS_CONST_EXPR(to_kind)); + else if constexpr (get_complexity(MP_UNITS_IS_CONST_EXPR(from_kind)) > get_complexity(MP_UNITS_IS_CONST_EXPR(to_kind))) return exploded_kind_result( - convertible_impl(get_kind_tree_root(explode(From{}).quantity), To{})); + convertible_impl(get_kind_tree_root(explode(MP_UNITS_IS_CONST_EXPR(from_kind)).quantity), MP_UNITS_IS_CONST_EXPR(to_kind))); else return exploded_kind_result( - convertible_impl(From{}, get_kind_tree_root(explode(To{}).quantity))); + convertible_impl(MP_UNITS_IS_CONST_EXPR(from_kind), get_kind_tree_root(explode(MP_UNITS_IS_CONST_EXPR(to_kind)).quantity))); } template -[[nodiscard]] consteval specs_convertible_result convertible_named(From, To) +[[nodiscard]] consteval specs_convertible_result convertible_named(From from, To to) { using enum specs_convertible_result; @@ -1369,16 +1369,16 @@ 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_impl(explode(MP_UNITS_IS_CONST_EXPR(from)).quantity, MP_UNITS_IS_CONST_EXPR(to)); else { - auto res = explode(To{}); - return min(res.result, convertible_impl(From{}, res.quantity)); + auto res = explode(MP_UNITS_IS_CONST_EXPR(to)); + return min(res.result, convertible_impl(MP_UNITS_IS_CONST_EXPR(from), res.quantity)); } } } template -[[nodiscard]] consteval specs_convertible_result convertible_impl(From, To) +[[nodiscard]] consteval specs_convertible_result convertible_impl(From from, To to) { using enum specs_convertible_result; @@ -1388,30 +1388,30 @@ template else if constexpr (From::dimension != To::dimension) return no; else if constexpr (QuantityKindSpec || QuantityKindSpec) - return convertible_kinds(get_kind_tree_root(From{}), get_kind_tree_root(To{})); - else if constexpr (NestedQuantityKindSpecOf && get_kind_tree_root(To{}) == To{}) + return convertible_kinds(get_kind_tree_root(MP_UNITS_IS_CONST_EXPR(from)), get_kind_tree_root(MP_UNITS_IS_CONST_EXPR(to))); + else if constexpr (NestedQuantityKindSpecOf && get_kind_tree_root(To{}) == To{}) return yes; - else if constexpr (NamedQuantitySpec && NamedQuantitySpec) { - return convertible_named(From{}, To{}); - } else if constexpr (DerivedQuantitySpec && DerivedQuantitySpec) { - return are_ingredients_convertible(From{}, To{}); - } else if constexpr (DerivedQuantitySpec) { - auto res = explode(From{}); + else if constexpr (NamedQuantitySpec && NamedQuantitySpec) + return convertible_named(MP_UNITS_IS_CONST_EXPR(from), MP_UNITS_IS_CONST_EXPR(to)); + else if constexpr (DerivedQuantitySpec && DerivedQuantitySpec) + return are_ingredients_convertible(from, MP_UNITS_IS_CONST_EXPR(to)); + else if constexpr (DerivedQuantitySpec) { + auto res = explode(MP_UNITS_IS_CONST_EXPR(from)); if constexpr (NamedQuantitySpec) - return convertible_impl(res.quantity, To{}); - else if constexpr (requires { To{}._equation_; }) { - auto eq = explode_to_equation(To{}); + return convertible_impl(res.quantity, MP_UNITS_IS_CONST_EXPR(to)); + else if constexpr (requires { MP_UNITS_IS_CONST_EXPR(to)._equation_; }) { + auto eq = explode_to_equation(MP_UNITS_IS_CONST_EXPR(to)); return min(eq.result, convertible_impl(res.quantity, eq.equation)); } else - return are_ingredients_convertible(From{}, To{}); + return are_ingredients_convertible(MP_UNITS_IS_CONST_EXPR(from), MP_UNITS_IS_CONST_EXPR(to)); } else if constexpr (DerivedQuantitySpec) { - auto res = explode(To{}); + auto res = explode(MP_UNITS_IS_CONST_EXPR(to)); if constexpr (NamedQuantitySpec) - return min(res.result, convertible_impl(From{}, res.quantity)); - else if constexpr (requires { From{}._equation_; }) - return min(res.result, convertible_impl(From{}._equation_, res.quantity)); + return min(res.result, convertible_impl(MP_UNITS_IS_CONST_EXPR(from), res.quantity)); + else if constexpr (requires { MP_UNITS_IS_CONST_EXPR(from)._equation_; }) + return min(res.result, convertible_impl(MP_UNITS_IS_CONST_EXPR(from)._equation_, res.quantity)); else - return min(res.result, are_ingredients_convertible(From{}, To{})); + return min(res.result, are_ingredients_convertible(MP_UNITS_IS_CONST_EXPR(from), MP_UNITS_IS_CONST_EXPR(to))); } // NOLINTEND(bugprone-branch-clone) return no; @@ -1498,7 +1498,7 @@ MP_UNITS_EXPORT_BEGIN template [[nodiscard]] consteval detail::QuantityKindSpec auto get_kind(Q q) { - return kind_of; + return kind_of; } [[nodiscard]] consteval QuantitySpec auto common_quantity_spec(QuantitySpec auto q) { return q; } diff --git a/src/core/include/mp-units/framework/reference.h b/src/core/include/mp-units/framework/reference.h index a0452b51..a2d3ae1a 100644 --- a/src/core/include/mp-units/framework/reference.h +++ b/src/core/include/mp-units/framework/reference.h @@ -288,9 +288,9 @@ template } -> Unit; } { - return detail::reference_t{}; + common_unit(get_unit(MP_UNITS_IS_CONST_EXPR(r1)), get_unit(MP_UNITS_IS_CONST_EXPR(r2)), get_unit(rest)...)>{}; } MP_UNITS_EXPORT_END diff --git a/src/core/include/mp-units/framework/unit.h b/src/core/include/mp-units/framework/unit.h index b00d4792..ba39dbb8 100644 --- a/src/core/include/mp-units/framework/unit.h +++ b/src/core/include/mp-units/framework/unit.h @@ -633,7 +633,7 @@ template template [[nodiscard]] consteval Unit auto common_unit(U1 u1, U2 u2) - requires(convertible(U1{}, U2{})) + requires(convertible(MP_UNITS_IS_CONST_EXPR(u1), MP_UNITS_IS_CONST_EXPR(u2))) { if constexpr (is_same_v) return u1;