From d69e223b0c71980c9f3a7dd551e0bd60bdb8d082 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Mon, 7 Nov 2022 16:14:02 -1000 Subject: [PATCH] refactor: `quantity_cast` on quantities refactored for V2 --- src/core/include/units/quantity_cast.h | 72 ++++++++++---------------- 1 file changed, 28 insertions(+), 44 deletions(-) diff --git a/src/core/include/units/quantity_cast.h b/src/core/include/units/quantity_cast.h index 59df535b..c1c835fe 100644 --- a/src/core/include/units/quantity_cast.h +++ b/src/core/include/units/quantity_cast.h @@ -50,39 +50,25 @@ class quantity; namespace detail { -// template -// inline constexpr Magnitude auto quantity_magnitude = decltype(Q::reference)::mag; +template +struct cast_traits; -// template -// inline constexpr Magnitude auto cast_magnitude = [] { -// using FromU = TYPENAME QFrom::unit; -// using ToU = TYPENAME QTo::unit; -// if constexpr (same_unit_reference::value) { -// return FromU::mag / ToU::mag; -// } else { -// return quantity_magnitude / quantity_magnitude; -// } -// }(); +template + requires common_type_with_, std::intmax_t> +struct cast_traits { + using multiplier_type = std::common_type_t, std::intmax_t>; + using rep_type = multiplier_type; +}; -// template -// struct cast_traits; - -// template -// requires common_type_with_, std::intmax_t> -// struct cast_traits { -// using ratio_type = std::common_type_t, std::intmax_t>; -// using rep_type = ratio_type; -// }; - -// template -// requires(!common_type_with_, std::intmax_t> && -// scalable_number_, std::intmax_t> && -// requires { typename std::common_type_t::value_type; } && -// common_type_with_::value_type, std::intmax_t>) -// struct cast_traits { -// using ratio_type = std::common_type_t::value_type, std::intmax_t>; -// using rep_type = std::common_type_t; -// }; +template + requires(!common_type_with_, std::intmax_t> && + scalable_number_, std::intmax_t> && + requires { typename std::common_type_t::value_type; } && + common_type_with_::value_type, std::intmax_t>) +struct cast_traits { + using multiplier_type = std::common_type_t::value_type, std::intmax_t>; + using rep_type = std::common_type_t; +}; } // namespace detail @@ -105,19 +91,17 @@ template Rep> if constexpr (R.unit == To::unit) { return To(static_cast(q.number())); } else { - // using traits = detail::cast_traits; - // using ratio_type = TYPENAME traits::ratio_type; - // using rep_type = TYPENAME traits::rep_type; + using traits = detail::cast_traits; + using multiplier_type = TYPENAME traits::multiplier_type; + using rep_type = TYPENAME traits::rep_type; - // constexpr Magnitude auto c_mag = detail::cast_magnitude, To>; - // constexpr Magnitude auto num = numerator(c_mag); - // constexpr Magnitude auto den = denominator(c_mag); - // constexpr Magnitude auto irr = c_mag * (den / num); + constexpr Magnitude auto c_mag = detail::get_canonical_unit(R.unit).mag / detail::get_canonical_unit(To::unit).mag; + constexpr Magnitude auto num = numerator(c_mag); + constexpr Magnitude auto den = denominator(c_mag); + constexpr Magnitude auto irr = c_mag * (den / num); - // constexpr auto val = [](Magnitude auto m) { return get_value(m); }; - // return To(static_cast(static_cast(q.number()) * val(num) / val(den) * val(irr))); - // TODO implement that - return q; + constexpr auto val = [](Magnitude auto m) { return get_value(m); }; + return To(static_cast(static_cast(q.number()) * val(num) / val(den) * val(irr))); } } @@ -161,7 +145,7 @@ template requires(convertible(ToD, R.dimension)) [[nodiscard]] constexpr auto quantity_cast(const quantity& q) { - constexpr reference, std::remove_const_t> r; + constexpr reference, typename quantity::unit_t> r; return quantity_cast>(q); } @@ -181,7 +165,7 @@ template requires(convertible(ToU, R.unit)) [[nodiscard]] constexpr auto quantity_cast(const quantity& q) { - constexpr reference, std::remove_const_t> r; + constexpr reference::dimension_t, std::remove_const_t> r; return quantity_cast>(q); }