refactor: DerivedFromQuantityKindSpecOf introduced to remove code duplications

This commit is contained in:
Mateusz Pusz
2023-06-13 17:32:52 +03:00
parent 9ab8136c98
commit 8ed82dfe96
3 changed files with 17 additions and 13 deletions

View File

@@ -143,4 +143,17 @@ template<typename T>
concept QuantitySpec = concept QuantitySpec =
detail::NamedQuantitySpec<T> || detail::IntermediateDerivedQuantitySpec<T> || detail::QuantityKindSpec<T>; detail::NamedQuantitySpec<T> || detail::IntermediateDerivedQuantitySpec<T> || detail::QuantityKindSpec<T>;
template<QuantitySpec Q>
[[nodiscard]] consteval QuantitySpec auto get_kind(Q q);
namespace detail {
template<auto To, auto From>
concept DerivedFromQuantityKindSpecOf =
QuantitySpec<std::remove_const_t<decltype(From)>> && QuantitySpec<std::remove_const_t<decltype(To)>> &&
get_kind(From) != get_kind(To) &&
std::derived_from<std::remove_cvref_t<decltype(To)>, std::remove_cvref_t<decltype(get_kind(From))>>;
}
} // namespace mp_units } // namespace mp_units

View File

@@ -188,7 +188,6 @@ concept UnitOf = AssociatedUnit<U> && QuantitySpec<std::remove_const_t<decltype(
implicitly_convertible(get_quantity_spec(U{}), QS) && implicitly_convertible(get_quantity_spec(U{}), QS) &&
// the below is to make `dimensionless[radian]` invalid // the below is to make `dimensionless[radian]` invalid
(get_kind(QS) == get_kind(get_quantity_spec(U{})) || (get_kind(QS) == get_kind(get_quantity_spec(U{})) ||
!std::derived_from<std::remove_const_t<decltype(get_quantity_spec(U{}))>, !detail::DerivedFromQuantityKindSpecOf<get_quantity_spec(U{}), QS>);
std::remove_const_t<decltype(get_kind(QS))>>);
} // namespace mp_units } // namespace mp_units

View File

@@ -433,9 +433,6 @@ struct derived_quantity_spec :
*/ */
QUANTITY_SPEC(dimensionless, derived_quantity_spec<>{}); QUANTITY_SPEC(dimensionless, derived_quantity_spec<>{});
template<QuantitySpec Q>
[[nodiscard]] consteval QuantitySpec auto get_kind(Q q);
/** /**
* @brief Quantity kind specifier * @brief Quantity kind specifier
* *
@@ -1331,10 +1328,7 @@ template<QuantitySpec From, QuantitySpec To>
else else
return exploded_kind_result( return exploded_kind_result(
convertible_impl(from_kind, get_kind(explode<get_complexity(from_kind)>(to_kind).quantity))); convertible_impl(from_kind, get_kind(explode<get_complexity(from_kind)>(to_kind).quantity)));
} else if constexpr (get_kind(from) != get_kind(to) && } else if constexpr (DerivedFromQuantityKindSpecOf<get_kind(to), from> && get_kind(to) == to)
std::derived_from<std::remove_cvref_t<decltype(get_kind(to))>,
std::remove_cvref_t<decltype(get_kind(from))>> &&
get_kind(to) == to)
return yes; return yes;
else if constexpr (NamedQuantitySpec<From> && NamedQuantitySpec<To>) { else if constexpr (NamedQuantitySpec<From> && NamedQuantitySpec<To>) {
if constexpr (have_common_base(from, to)) { if constexpr (have_common_base(from, to)) {
@@ -1461,11 +1455,9 @@ template<QuantitySpec Q1, QuantitySpec Q2>
using QQ2 = std::remove_const_t<decltype(remove_kind(q2))>; using QQ2 = std::remove_const_t<decltype(remove_kind(q2))>;
if constexpr (is_same_v<Q1, Q2>) if constexpr (is_same_v<Q1, Q2>)
return q1; return q1;
else if constexpr (get_kind(q1) != get_kind(q2) && std::derived_from<std::remove_const_t<decltype(get_kind(q1))>, else if constexpr (detail::DerivedFromQuantityKindSpecOf<q1, q2>)
std::remove_const_t<decltype(get_kind(q2))>>)
return remove_kind(q1); return remove_kind(q1);
else if constexpr (get_kind(q1) != get_kind(q2) && std::derived_from<std::remove_const_t<decltype(get_kind(q2))>, else if constexpr (detail::DerivedFromQuantityKindSpecOf<q2, q1>)
std::remove_const_t<decltype(get_kind(q1))>>)
return remove_kind(q2); return remove_kind(q2);
else if constexpr ((detail::QuantityKindSpec<Q1> && !detail::QuantityKindSpec<Q2>) || else if constexpr ((detail::QuantityKindSpec<Q1> && !detail::QuantityKindSpec<Q2>) ||
(detail::IntermediateDerivedQuantitySpec<QQ1> && detail::NamedQuantitySpec<QQ2> && (detail::IntermediateDerivedQuantitySpec<QQ1> && detail::NamedQuantitySpec<QQ2> &&