refactor: cast_ratio now uses quantity_ratio

This commit is contained in:
Mateusz Pusz
2020-09-07 11:11:12 +02:00
parent f3d9828abd
commit 00cb2cd6c3
2 changed files with 25 additions and 10 deletions

View File

@@ -44,10 +44,10 @@ concept safe_convertible = // exposition only
std::convertible_to<From, To> &&
(treat_as_floating_point<To> || (!treat_as_floating_point<From>));
template<typename Rep, typename UnitFrom, typename UnitTo>
template<typename Rep, typename QuantityFrom, typename QuantityTo>
concept safe_divisible = // exposition only
treat_as_floating_point<Rep> ||
is_integral(UnitFrom::ratio / UnitTo::ratio);
is_integral(quantity_ratio(QuantityFrom{}) / quantity_ratio(QuantityTo{}));
} // namespace detail
@@ -81,7 +81,7 @@ public:
template<Quantity Q2>
requires equivalent_dim<D, typename Q2::dimension> &&
detail::safe_convertible<typename Q2::rep, rep> &&
detail::safe_divisible<rep, typename Q2::unit, unit>
detail::safe_divisible<rep, Q2, quantity>
constexpr quantity(const Q2& q) : value_{quantity_cast<quantity>(q).count()} {}
quantity& operator=(const quantity&) = default;

View File

@@ -38,6 +38,21 @@
namespace units {
namespace detail {
template<typename D, typename U, typename Rep>
constexpr auto quantity_ratio(const quantity<D, U, Rep>&)
{
if constexpr(BaseDimension<D>) {
return U::ratio;
}
else {
return D::base_units_ratio * U::ratio / D::coherent_unit::ratio;
}
}
} // namespace detail
// QuantityOf
template<typename T, typename Dim>
concept QuantityOf = Quantity<T> && Dimension<Dim> && equivalent_dim<typename T::dimension, Dim>;
@@ -266,16 +281,16 @@ struct quantity_cast_impl<To, CRatio, CRep, false, true, false> {
}
};
template<Dimension FromD, Unit FromU, Dimension ToD, Unit ToU>
constexpr ratio cast_ratio()
template<typename Q1, typename Q2>
constexpr ratio cast_ratio(const Q1& from, const Q2& to)
{
if constexpr(BaseDimension<FromD> || same_unit_reference<FromU, ToU>::value) {
using FromU = Q1::unit;
using ToU = Q2::unit;
if constexpr(same_unit_reference<FromU, ToU>::value) {
return FromU::ratio / ToU::ratio;
}
else {
const ratio from_ratio = FromD::base_units_ratio * FromU::ratio;
const ratio to_ratio = ToD::base_units_ratio * ToU::ratio;
return from_ratio / to_ratio;
return quantity_ratio(from) / quantity_ratio(to);
}
}
@@ -297,7 +312,7 @@ template<Quantity To, typename D, typename U, typename Rep>
[[nodiscard]] constexpr auto quantity_cast(const quantity<D, U, Rep>& q)
requires QuantityOf<To, D>
{
using c_ratio = std::integral_constant<ratio, detail::cast_ratio<D, U, typename To::dimension, typename To::unit>()>;
using c_ratio = std::integral_constant<ratio, detail::cast_ratio(quantity<D, U, Rep>(), To())>;
using c_rep = std::common_type_t<typename To::rep, Rep>;
using ret_unit = downcast_unit<typename To::dimension, To::unit::ratio>;
using ret = quantity<typename To::dimension, ret_unit, typename To::rep>;