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 {
|
||||
|
||||
template<AssociatedUnit U>
|
||||
[[nodiscard]] consteval auto all_are_kinds(U);
|
||||
|
||||
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>
|
||||
[[nodiscard]] consteval auto get_associated_quantity(type_list<Us...>)
|
||||
template<typename... Nums, typename... Dens>
|
||||
[[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>
|
||||
[[nodiscard]] consteval auto get_associated_quantity(U)
|
||||
[[nodiscard]] consteval auto all_are_kinds(U)
|
||||
{
|
||||
if constexpr (requires { U::reference_unit; })
|
||||
return get_associated_quantity(U::reference_unit);
|
||||
else if constexpr (requires { typename U::_num_; })
|
||||
return get_associated_quantity(typename U::_num_{}) / get_associated_quantity(typename U::_den_{});
|
||||
else if constexpr (requires { U::quantity_spec; })
|
||||
return U::quantity_spec;
|
||||
if constexpr (requires { U::quantity_spec; })
|
||||
return QuantityKindSpec<std::remove_const_t<decltype(U::quantity_spec)>>;
|
||||
else if constexpr (requires { U::reference_unit; })
|
||||
return all_are_kinds(U::reference_unit);
|
||||
else if constexpr (requires { typename U::_num_; }) {
|
||||
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
|
||||
|
Reference in New Issue
Block a user