mirror of
https://github.com/mpusz/mp-units.git
synced 2025-07-31 19:04:27 +02:00
refactor: DerivedFromQuantityKindSpecOf
introduced to remove code duplications
This commit is contained in:
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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> &&
|
||||||
|
Reference in New Issue
Block a user