From 1bc6fdece9c0139d9beeaa2f99baa8c7fe643e93 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 24 Aug 2023 19:21:17 +0200 Subject: [PATCH] fix: clang compilation workarounds added for magnitudes --- src/core/include/mp-units/bits/magnitude.h | 38 +++++++++++++--------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/core/include/mp-units/bits/magnitude.h b/src/core/include/mp-units/bits/magnitude.h index 6c1dc9ec..9b193fe3 100644 --- a/src/core/include/mp-units/bits/magnitude.h +++ b/src/core/include/mp-units/bits/magnitude.h @@ -107,7 +107,7 @@ concept Magnitude = detail::is_magnitude; /** * @brief A basis vector in our magnitude representation, raised to some rational power. * - * The public API is that there is a `power` member variable (of type `ratio`), and a `get_base()` member function (of + * The public API is that there is a `power` member variable (of type `ratio`), and a `get_base_value()` member function (of * type either `std::intmax_t` or `long double`, as appropriate), for any specialization. * * These types exist to be used as NTTPs for the variadic `magnitude<...>` template. We represent a magnitude (which is @@ -185,6 +185,14 @@ template [[nodiscard]] consteval auto get_base(Element element) { if constexpr (detail::is_specialization_of_power_v) return Element::base; + else + return element; +} + +template +[[nodiscard]] consteval auto get_base_value(Element element) +{ + if constexpr (detail::is_specialization_of_power_v) return get_base_value(Element::base); #if MP_UNITS_COMP_CLANG else if constexpr (is_specialization_of) return element.value; @@ -234,15 +242,13 @@ template template [[nodiscard]] consteval auto power_v_or_T() { - constexpr auto shortT = shorten_T(); - if constexpr (R.den == 1) { if constexpr (R.num == 1) - return shortT; + return shorten_T(); else - return power_v{}; + return power_v(), R.num>{}; } else { - return power_v{}; + return power_v(), R.num, R.den>{}; } } @@ -319,7 +325,7 @@ template } auto power = exp.num; - return int_power(static_cast>(get_base(el)), power); + return int_power(static_cast>(get_base_value(el)), power); } // A converter for the value member variable of magnitude (below). @@ -382,13 +388,13 @@ namespace detail { // if (get_exponent(element) == 0) { // return false; // } -// if constexpr (std::integral) { +// if constexpr (std::integral) { // // Some prime numbers are so big, that we can't check their primality without exhausting limits on constexpr // steps // // and/or iterations. We can still _perform_ the factorization for these by using the `known_first_factor` // // workaround. However, we can't _check_ that they are prime, because this workaround depends on the input being // // usable in a constexpr expression. This is true for `prime_factorization` (below), where the input `N` is a -// // template parameter, but is not true for our case, where the input `bp.get_base()` is a function parameter. +// // template parameter, but is not true for our case, where the input `bp.get_base_value()` is a function parameter. // (See // // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1045r1.html for some background reading on this // // distinction.) @@ -575,13 +581,13 @@ namespace detail { consteval bool less(MagnitudeSpec auto lhs, MagnitudeSpec auto rhs) { - using lhs_base_t = decltype(get_base(lhs)); - using rhs_base_t = decltype(get_base(rhs)); + using lhs_base_t = decltype(get_base_value(lhs)); + using rhs_base_t = decltype(get_base_value(rhs)); if constexpr (is_named_magnitude && is_named_magnitude) return type_name() < type_name(); else if constexpr (!is_named_magnitude && !is_named_magnitude) - return get_base(lhs) < get_base(rhs); + return get_base_value(lhs) < get_base_value(rhs); else return is_named_magnitude; } @@ -731,10 +737,10 @@ template { using detail::remove_positive_power; - if constexpr (detail::get_base(H1) < detail::get_base(H2)) { + if constexpr (detail::get_base_value(H1) < detail::get_base_value(H2)) { // When H1 has the smaller base, prepend to result from recursion. return remove_positive_power(magnitude

{}) * common_magnitude(magnitude{}, magnitude{}); - } else if constexpr (detail::get_base(H2) < detail::get_base(H1)) { + } else if constexpr (detail::get_base_value(H2) < detail::get_base_value(H1)) { // When H2 has the smaller base, prepend to result from recursion. return remove_positive_power(magnitude

{}) * common_magnitude(magnitude{}, magnitude{}); } else { @@ -751,7 +757,7 @@ template template [[nodiscard]] consteval auto common_magnitude_type_impl(magnitude) { - return (... * decltype(get_base(Ms)){}) * std::intmax_t{}; + return (... * decltype(get_base_value(Ms)){}) * std::intmax_t{}; } // Returns the most precise type to express the magnitude factor @@ -828,7 +834,7 @@ namespace detail { template [[nodiscard]] consteval ratio get_power(T base, magnitude) { - return ((get_base(Ms) == base ? get_exponent(Ms) : ratio{0}) + ... + ratio{0}); + return ((get_base_value(Ms) == base ? get_exponent(Ms) : ratio{0}) + ... + ratio{0}); } [[nodiscard]] consteval std::intmax_t integer_part(ratio r) { return r.num / r.den; }