Skip to content

Commit

Permalink
refactor: integral conversion factor optimized for the case of the sa…
Browse files Browse the repository at this point in the history
…me unit type
  • Loading branch information
mpusz committed Jun 6, 2024
1 parent 3353f49 commit 452c601
Showing 1 changed file with 10 additions and 5 deletions.
15 changes: 10 additions & 5 deletions src/core/include/mp-units/framework/quantity.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,22 @@ namespace mp_units {

namespace detail {

template<auto UFrom, auto UTo>
concept IntegralConversionFactor = Unit<decltype(UFrom)> && Unit<decltype(UTo)> &&
decltype(is_integral(decltype(decltype(get_canonical_unit(UFrom))::mag /
decltype(get_canonical_unit(UTo))::mag){}))::value;
template<Unit UFrom, Unit UTo>
[[nodiscard]] consteval bool integral_conversion_factor(UFrom from, UTo to)
{
if constexpr (is_same_v<UFrom, UTo>)
return true;
else
return decltype(is_integral(
decltype(decltype(get_canonical_unit(from))::mag / decltype(get_canonical_unit(to))::mag){}))::value;
}

template<typename QFrom, typename QTo>
concept QuantityConvertibleTo =
Quantity<QFrom> && Quantity<QTo> && implicitly_convertible(QFrom::quantity_spec, QTo::quantity_spec) &&
convertible(QFrom::unit, QTo::unit) &&
(treat_as_floating_point<typename QTo::rep> ||
(!treat_as_floating_point<typename QFrom::rep> && IntegralConversionFactor<QFrom::unit, QTo::unit>)) &&
(!treat_as_floating_point<typename QFrom::rep> && (integral_conversion_factor(QFrom::unit, QTo::unit)))) &&
// TODO consider providing constraints of sudo_cast here rather than testing if it can be called (its return type is
// deduced thus the function is evaluated here and may emit truncating conversion or other warnings)
requires(QFrom q) { detail::sudo_cast<QTo>(q); };
Expand Down

0 comments on commit 452c601

Please sign in to comment.