forked from mpusz/mp-units
refactor: cast_ratio now uses quantity_ratio
This commit is contained in:
@@ -44,10 +44,10 @@ concept safe_convertible = // exposition only
|
|||||||
std::convertible_to<From, To> &&
|
std::convertible_to<From, To> &&
|
||||||
(treat_as_floating_point<To> || (!treat_as_floating_point<From>));
|
(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
|
concept safe_divisible = // exposition only
|
||||||
treat_as_floating_point<Rep> ||
|
treat_as_floating_point<Rep> ||
|
||||||
is_integral(UnitFrom::ratio / UnitTo::ratio);
|
is_integral(quantity_ratio(QuantityFrom{}) / quantity_ratio(QuantityTo{}));
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ public:
|
|||||||
template<Quantity Q2>
|
template<Quantity Q2>
|
||||||
requires equivalent_dim<D, typename Q2::dimension> &&
|
requires equivalent_dim<D, typename Q2::dimension> &&
|
||||||
detail::safe_convertible<typename Q2::rep, rep> &&
|
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()} {}
|
constexpr quantity(const Q2& q) : value_{quantity_cast<quantity>(q).count()} {}
|
||||||
|
|
||||||
quantity& operator=(const quantity&) = default;
|
quantity& operator=(const quantity&) = default;
|
||||||
|
@@ -38,6 +38,21 @@
|
|||||||
|
|
||||||
namespace units {
|
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
|
// QuantityOf
|
||||||
template<typename T, typename Dim>
|
template<typename T, typename Dim>
|
||||||
concept QuantityOf = Quantity<T> && Dimension<Dim> && equivalent_dim<typename T::dimension, 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>
|
template<typename Q1, typename Q2>
|
||||||
constexpr ratio cast_ratio()
|
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;
|
return FromU::ratio / ToU::ratio;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const ratio from_ratio = FromD::base_units_ratio * FromU::ratio;
|
return quantity_ratio(from) / quantity_ratio(to);
|
||||||
const ratio to_ratio = ToD::base_units_ratio * ToU::ratio;
|
|
||||||
return from_ratio / to_ratio;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,7 +312,7 @@ template<Quantity To, typename D, typename U, typename Rep>
|
|||||||
[[nodiscard]] constexpr auto quantity_cast(const quantity<D, U, Rep>& q)
|
[[nodiscard]] constexpr auto quantity_cast(const quantity<D, U, Rep>& q)
|
||||||
requires QuantityOf<To, D>
|
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 c_rep = std::common_type_t<typename To::rep, Rep>;
|
||||||
using ret_unit = downcast_unit<typename To::dimension, To::unit::ratio>;
|
using ret_unit = downcast_unit<typename To::dimension, To::unit::ratio>;
|
||||||
using ret = quantity<typename To::dimension, ret_unit, typename To::rep>;
|
using ret = quantity<typename To::dimension, ret_unit, typename To::rep>;
|
||||||
|
Reference in New Issue
Block a user