[hacks] add MP_UNITS_IS_CONST_EXPR(from)

This commit is contained in:
Jonas Hoppe
2024-09-03 12:27:57 +02:00
parent a89bfc6c21
commit 48c4f297c8
5 changed files with 40 additions and 38 deletions

View File

@@ -76,9 +76,9 @@ template<AssociatedUnit U>
template<AssociatedUnit U> template<AssociatedUnit U>
[[nodiscard]] consteval auto get_associated_quantity(U u) [[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) if constexpr (all_kinds)
return kind_of<get_associated_quantity_impl(U{})>; return kind_of<get_associated_quantity_impl(MP_UNITS_IS_CONST_EXPR(u))>;
else else
return get_associated_quantity_impl(u); return get_associated_quantity_impl(u);
} }

View File

@@ -82,12 +82,14 @@
#define MP_UNITS_TYPENAME typename #define MP_UNITS_TYPENAME typename
#define MP_UNITS_EXPRESSION(x) (x) #define MP_UNITS_EXPRESSION(x) (x)
#define MP_UNITS_IS_VALUE(x) (x) #define MP_UNITS_IS_VALUE(x) (x)
#define MP_UNITS_IS_CONST_EXPR(x) decltype(x){}
#else #else
#define MP_UNITS_TYPENAME #define MP_UNITS_TYPENAME
#define MP_UNITS_EXPRESSION(x) x #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 #endif

View File

@@ -673,9 +673,9 @@ template<QuantitySpec Q>
template<Dimension D1, Dimension D2> template<Dimension D1, Dimension D2>
[[nodiscard]] consteval bool ingredients_dimension_less(D1 lhs, D2 rhs) [[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; return false;
else if constexpr (D2{} == dimension_one) else if constexpr (MP_UNITS_IS_CONST_EXPR(rhs) == dimension_one)
return true; return true;
else else
return detail::type_name<D1>() < detail::type_name<D2>(); return detail::type_name<D1>() < detail::type_name<D2>();
@@ -1338,25 +1338,25 @@ template<NamedQuantitySpec From, DerivedQuantitySpec To>
} }
template<QuantitySpec From, QuantitySpec To> template<QuantitySpec From, QuantitySpec To>
[[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) { constexpr auto exploded_kind_result = [](specs_convertible_result res) {
using enum specs_convertible_result; using enum specs_convertible_result;
return res == no ? no : yes; return res == no ? no : yes;
}; };
if constexpr ((NamedQuantitySpec<decltype(From{})> && NamedQuantitySpec<decltype(To{})>) || if constexpr ((NamedQuantitySpec<decltype(MP_UNITS_IS_CONST_EXPR(from_kind))> && NamedQuantitySpec<decltype(MP_UNITS_IS_CONST_EXPR(to_kind))>) ||
get_complexity(From{}) == get_complexity(To{})) get_complexity(MP_UNITS_IS_CONST_EXPR(from_kind)) == get_complexity(MP_UNITS_IS_CONST_EXPR(to_kind)))
return convertible_impl(From{}, To{}); return convertible_impl(MP_UNITS_IS_CONST_EXPR(from_kind), MP_UNITS_IS_CONST_EXPR(to_kind));
else if constexpr (get_complexity(From{}) > get_complexity(To{})) 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( return exploded_kind_result(
convertible_impl(get_kind_tree_root(explode<get_complexity(To{})>(From{}).quantity), To{})); convertible_impl(get_kind_tree_root(explode<get_complexity(MP_UNITS_IS_CONST_EXPR(to_kind))>(MP_UNITS_IS_CONST_EXPR(from_kind)).quantity), MP_UNITS_IS_CONST_EXPR(to_kind)));
else else
return exploded_kind_result( return exploded_kind_result(
convertible_impl(From{}, get_kind_tree_root(explode<get_complexity(From{})>(To{}).quantity))); convertible_impl(MP_UNITS_IS_CONST_EXPR(from_kind), get_kind_tree_root(explode<get_complexity(MP_UNITS_IS_CONST_EXPR(from_kind))>(MP_UNITS_IS_CONST_EXPR(to_kind)).quantity)));
} }
template<NamedQuantitySpec From, NamedQuantitySpec To> template<NamedQuantitySpec From, NamedQuantitySpec To>
[[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; using enum specs_convertible_result;
@@ -1369,16 +1369,16 @@ template<NamedQuantitySpec From, NamedQuantitySpec To>
return no; return no;
else if constexpr (get_complexity(From{}) != get_complexity(To{})) { else if constexpr (get_complexity(From{}) != get_complexity(To{})) {
if constexpr (get_complexity(From{}) > get_complexity(To{})) if constexpr (get_complexity(From{}) > get_complexity(To{}))
return convertible_impl(explode<get_complexity(To{})>(From{}).quantity, To{}); return convertible_impl(explode<get_complexity(MP_UNITS_IS_CONST_EXPR(to))>(MP_UNITS_IS_CONST_EXPR(from)).quantity, MP_UNITS_IS_CONST_EXPR(to));
else { else {
auto res = explode<get_complexity(From{})>(To{}); auto res = explode<get_complexity(MP_UNITS_IS_CONST_EXPR(from))>(MP_UNITS_IS_CONST_EXPR(to));
return min(res.result, convertible_impl(From{}, res.quantity)); return min(res.result, convertible_impl(MP_UNITS_IS_CONST_EXPR(from), res.quantity));
} }
} }
} }
template<QuantitySpec From, QuantitySpec To> template<QuantitySpec From, QuantitySpec To>
[[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; using enum specs_convertible_result;
@@ -1388,30 +1388,30 @@ template<QuantitySpec From, QuantitySpec To>
else if constexpr (From::dimension != To::dimension) else if constexpr (From::dimension != To::dimension)
return no; return no;
else if constexpr (QuantityKindSpec<From> || QuantityKindSpec<To>) else if constexpr (QuantityKindSpec<From> || QuantityKindSpec<To>)
return convertible_kinds(get_kind_tree_root(From{}), get_kind_tree_root(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{}), From{}> && get_kind_tree_root(To{}) == To{}) else if constexpr (NestedQuantityKindSpecOf<get_kind_tree_root(To{}), from> && get_kind_tree_root(To{}) == To{})
return yes; return yes;
else if constexpr (NamedQuantitySpec<From> && NamedQuantitySpec<To>) { else if constexpr (NamedQuantitySpec<From> && NamedQuantitySpec<To>)
return convertible_named(From{}, To{}); return convertible_named(MP_UNITS_IS_CONST_EXPR(from), MP_UNITS_IS_CONST_EXPR(to));
} else if constexpr (DerivedQuantitySpec<From> && DerivedQuantitySpec<To>) { else if constexpr (DerivedQuantitySpec<From> && DerivedQuantitySpec<To>)
return are_ingredients_convertible(From{}, To{}); return are_ingredients_convertible(from, MP_UNITS_IS_CONST_EXPR(to));
} else if constexpr (DerivedQuantitySpec<From>) { else if constexpr (DerivedQuantitySpec<From>) {
auto res = explode<get_complexity(To{})>(From{}); auto res = explode<get_complexity(MP_UNITS_IS_CONST_EXPR(to))>(MP_UNITS_IS_CONST_EXPR(from));
if constexpr (NamedQuantitySpec<decltype(res.quantity)>) if constexpr (NamedQuantitySpec<decltype(res.quantity)>)
return convertible_impl(res.quantity, To{}); return convertible_impl(res.quantity, MP_UNITS_IS_CONST_EXPR(to));
else if constexpr (requires { To{}._equation_; }) { else if constexpr (requires { MP_UNITS_IS_CONST_EXPR(to)._equation_; }) {
auto eq = explode_to_equation(To{}); auto eq = explode_to_equation(MP_UNITS_IS_CONST_EXPR(to));
return min(eq.result, convertible_impl(res.quantity, eq.equation)); return min(eq.result, convertible_impl(res.quantity, eq.equation));
} else } 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<To>) { } else if constexpr (DerivedQuantitySpec<To>) {
auto res = explode<get_complexity(From{})>(To{}); auto res = explode<get_complexity(MP_UNITS_IS_CONST_EXPR(from))>(MP_UNITS_IS_CONST_EXPR(to));
if constexpr (NamedQuantitySpec<decltype(res.quantity)>) if constexpr (NamedQuantitySpec<decltype(res.quantity)>)
return min(res.result, convertible_impl(From{}, res.quantity)); return min(res.result, convertible_impl(MP_UNITS_IS_CONST_EXPR(from), res.quantity));
else if constexpr (requires { From{}._equation_; }) else if constexpr (requires { MP_UNITS_IS_CONST_EXPR(from)._equation_; })
return min(res.result, convertible_impl(From{}._equation_, res.quantity)); return min(res.result, convertible_impl(MP_UNITS_IS_CONST_EXPR(from)._equation_, res.quantity));
else 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) // NOLINTEND(bugprone-branch-clone)
return no; return no;
@@ -1498,7 +1498,7 @@ MP_UNITS_EXPORT_BEGIN
template<QuantitySpec Q> template<QuantitySpec Q>
[[nodiscard]] consteval detail::QuantityKindSpec auto get_kind(Q q) [[nodiscard]] consteval detail::QuantityKindSpec auto get_kind(Q q)
{ {
return kind_of<detail::get_kind_tree_root(decltype(q){})>; return kind_of<detail::get_kind_tree_root(MP_UNITS_IS_CONST_EXPR(q))>;
} }
[[nodiscard]] consteval QuantitySpec auto common_quantity_spec(QuantitySpec auto q) { return q; } [[nodiscard]] consteval QuantitySpec auto common_quantity_spec(QuantitySpec auto q) { return q; }

View File

@@ -288,9 +288,9 @@ template<Reference R1, Reference R2, Reference... Rest>
} -> Unit; } -> Unit;
} }
{ {
return detail::reference_t<common_quantity_spec(get_quantity_spec(R1{}), get_quantity_spec(R2{}), return detail::reference_t<common_quantity_spec(get_quantity_spec(MP_UNITS_IS_CONST_EXPR(r1)), get_quantity_spec(MP_UNITS_IS_CONST_EXPR(r2)),
get_quantity_spec(rest)...), get_quantity_spec(rest)...),
common_unit(get_unit(R1{}), get_unit(R2{}), get_unit(rest)...)>{}; 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 MP_UNITS_EXPORT_END

View File

@@ -633,7 +633,7 @@ template<Unit From, Unit To>
template<Unit U1, Unit U2> template<Unit U1, Unit U2>
[[nodiscard]] consteval Unit auto common_unit(U1 u1, U2 u2) [[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<U1, U2>) if constexpr (is_same_v<U1, U2>)
return u1; return u1;