forked from mpusz/mp-units
feat: proper support of kinds added to get_associated_quantity()
This commit is contained in:
@@ -28,27 +28,59 @@
|
|||||||
|
|
||||||
namespace mp_units::detail {
|
namespace mp_units::detail {
|
||||||
|
|
||||||
|
template<AssociatedUnit U>
|
||||||
|
[[nodiscard]] consteval auto all_are_kinds(U);
|
||||||
|
|
||||||
template<typename U, auto... Vs>
|
template<typename U, auto... Vs>
|
||||||
[[nodiscard]] consteval auto get_associated_quantity(power<U, Vs...>)
|
[[nodiscard]] consteval auto all_are_kinds(power<U, Vs...>)
|
||||||
{
|
{
|
||||||
return pow<Vs...>(get_associated_quantity(U{}));
|
return all_are_kinds(U{});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Us>
|
template<typename... Nums, typename... Dens>
|
||||||
[[nodiscard]] consteval auto get_associated_quantity(type_list<Us...>)
|
[[nodiscard]] consteval bool all_are_kinds(type_list<Nums...>, type_list<Dens...>)
|
||||||
{
|
{
|
||||||
return (dimensionless * ... * get_associated_quantity(Us{}));
|
return (... && all_are_kinds(Nums{})) && (... && all_are_kinds(Dens{}));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<AssociatedUnit U>
|
template<AssociatedUnit U>
|
||||||
[[nodiscard]] consteval auto get_associated_quantity(U)
|
[[nodiscard]] consteval auto all_are_kinds(U)
|
||||||
{
|
{
|
||||||
if constexpr (requires { U::reference_unit; })
|
if constexpr (requires { U::quantity_spec; })
|
||||||
return get_associated_quantity(U::reference_unit);
|
return QuantityKindSpec<std::remove_const_t<decltype(U::quantity_spec)>>;
|
||||||
else if constexpr (requires { typename U::_num_; })
|
else if constexpr (requires { U::reference_unit; })
|
||||||
return get_associated_quantity(typename U::_num_{}) / get_associated_quantity(typename U::_den_{});
|
return all_are_kinds(U::reference_unit);
|
||||||
else if constexpr (requires { U::quantity_spec; })
|
else if constexpr (requires { typename U::_num_; }) {
|
||||||
return U::quantity_spec;
|
return all_are_kinds(typename U::_num_{}, typename U::_den_{});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<AssociatedUnit U>
|
||||||
|
[[nodiscard]] consteval auto get_associated_quantity_impl(U u);
|
||||||
|
|
||||||
|
template<AssociatedUnit U>
|
||||||
|
using to_quantity_spec = std::remove_const_t<decltype(get_associated_quantity_impl(U{}))>;
|
||||||
|
|
||||||
|
template<AssociatedUnit U>
|
||||||
|
[[nodiscard]] consteval auto get_associated_quantity_impl(U u)
|
||||||
|
{
|
||||||
|
if constexpr (requires { U::quantity_spec; })
|
||||||
|
return remove_kind(U::quantity_spec);
|
||||||
|
else if constexpr (requires { U::reference_unit; })
|
||||||
|
return get_associated_quantity_impl(U::reference_unit);
|
||||||
|
else if constexpr (requires { typename U::_num_; }) {
|
||||||
|
return expr_map<to_quantity_spec, derived_quantity_spec, struct dimensionless, type_list_of_quantity_spec_less>(u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<AssociatedUnit U>
|
||||||
|
[[nodiscard]] consteval auto get_associated_quantity(U u)
|
||||||
|
{
|
||||||
|
constexpr bool all_kinds = all_are_kinds(u);
|
||||||
|
if constexpr (all_kinds)
|
||||||
|
return kind_of<get_associated_quantity_impl(u)>;
|
||||||
|
else
|
||||||
|
return get_associated_quantity_impl(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mp_units::detail
|
} // namespace mp_units::detail
|
||||||
|
Reference in New Issue
Block a user