diff --git a/src/core/include/mp-units/framework/magnitude.h b/src/core/include/mp-units/framework/magnitude.h index 4cb50ed1..7159effc 100644 --- a/src/core/include/mp-units/framework/magnitude.h +++ b/src/core/include/mp-units/framework/magnitude.h @@ -234,8 +234,6 @@ template template [[nodiscard]] consteval auto remove_positive_power(magnitude m); -inline constexpr symbol_text base_multiplier(u8"× 10", "x 10"); - template requires detail::gt_zero [[nodiscard]] consteval Magnitude auto mag_power_lazy(); @@ -316,6 +314,31 @@ struct magnitude_base> { } }; +template +[[nodiscard]] consteval auto ratio_txt() +{ + if constexpr (den_value == 1) + return detail::regular(); + else + return detail::regular() + symbol_text("/") + detail::regular(); +}; + +template +[[nodiscard]] consteval auto magnitude_text_impl() +{ + constexpr auto num_value = get_value(num); + constexpr auto den_value = get_value(den); + + if constexpr (num_value == 1 && den_value == 1 && exp10 != 0) { + return symbol_text("10") + detail::superscript(); + } else { + if constexpr (exp10 == 0) + return ratio_txt(); + else + return ratio_txt() + symbol_text(u8" × 10", " x 10") + detail::superscript(); + } +} + } // namespace detail @@ -426,37 +449,28 @@ private: [[nodiscard]] friend consteval auto _magnitude_text(magnitude) { - constexpr auto exp10 = _extract_power_of_10(magnitude{}); - - constexpr Magnitude auto base = magnitude{} / detail::mag_power_lazy<10, exp10>(); - constexpr Magnitude auto num = _numerator(base); - constexpr Magnitude auto den = _denominator(base); - // TODO address the below - static_assert(base == num / den, "Printing rational powers, or irrational bases, not yet supported"); - - constexpr auto num_value = get_value(num); - constexpr auto den_value = get_value(den); - - if constexpr (num_value == 1 && den_value == 1 && exp10 != 0) { - return detail::base_multiplier + detail::superscript(); - } else if constexpr (num_value != 1 || den_value != 1 || exp10 != 0) { - auto txt = symbol_text("[") + detail::regular(); - if constexpr (den_value == 1) { - if constexpr (exp10 == 0) { - return txt + symbol_text("]"); - } else { - return txt + symbol_text(" ") + detail::base_multiplier + detail::superscript() + symbol_text("]"); - } - } else { - if constexpr (exp10 == 0) { - return txt + symbol_text("/") + detail::regular() + symbol_text("]"); - } else { - return txt + symbol_text("/") + detail::regular() + symbol_text(" ") + detail::base_multiplier + - detail::superscript() + symbol_text("]"); - } - } - } else { + if constexpr (magnitude{} == magnitude<1>{}) { return symbol_text(""); + } else { + constexpr auto exp10 = _extract_power_of_10(magnitude{}); + if constexpr (detail::abs(exp10) < 3) { + // print the value as a regular number (without exponent) + constexpr Magnitude auto num = _numerator(magnitude{}); + constexpr Magnitude auto den = _denominator(magnitude{}); + // TODO address the below + static_assert(magnitude{} == num / den, "Printing rational powers, or irrational bases, not yet supported"); + return detail::magnitude_text_impl(); + } else { + // print the value as a number with exponent + // if user wanted a regular number for this magnitude then probably a better scaled unit should be used + constexpr Magnitude auto base = magnitude{} / detail::mag_power_lazy<10, exp10>(); + constexpr Magnitude auto num = _numerator(base); + constexpr Magnitude auto den = _denominator(base); + + // TODO address the below + static_assert(base == num / den, "Printing rational powers, or irrational bases, not yet supported"); + return detail::magnitude_text_impl(); + } } } }; diff --git a/src/core/include/mp-units/framework/unit.h b/src/core/include/mp-units/framework/unit.h index 2bbbb67d..b5ed5837 100644 --- a/src/core/include/mp-units/framework/unit.h +++ b/src/core/include/mp-units/framework/unit.h @@ -830,16 +830,13 @@ template Out, auto M, typename U> constexpr Out unit_symbol_impl(Out out, const scaled_unit_impl& u, const unit_symbol_formatting& fmt, bool negative_power) { - if constexpr (M == mag<1>) { - // no ratio/prefix - return unit_symbol_impl(out, u.reference_unit, fmt, negative_power); - } else { - constexpr auto mag_txt = _magnitude_text(M); - out = copy(mag_txt, fmt.encoding, out); - - if constexpr (space_before_unit_symbol::reference_unit>) *out++ = ' '; - return unit_symbol_impl(out, u.reference_unit, fmt, negative_power); - } + *out++ = '['; + constexpr auto mag_txt = _magnitude_text(M); + out = copy(mag_txt, fmt.encoding, out); + if constexpr (space_before_unit_symbol::reference_unit>) *out++ = ' '; + unit_symbol_impl(out, u.reference_unit, fmt, negative_power); + *out++ = ']'; + return out; } template diff --git a/test/static/unit_symbol_test.cpp b/test/static/unit_symbol_test.cpp index 38048470..c861dd68 100644 --- a/test/static/unit_symbol_test.cpp +++ b/test/static/unit_symbol_test.cpp @@ -110,19 +110,29 @@ static_assert(unit_symbol(zebi) == "Zibit"); static_assert(unit_symbol(yobi) == "Yibit"); // scaled units -static_assert(unit_symbol(mag<100> * metre) == "× 10² m"); -static_assert(unit_symbol(mag<100> * metre) == "x 10^2 m"); -static_assert(unit_symbol(mag<60> * second) == "[6 × 10¹] s"); -static_assert(unit_symbol(mag<60> * second) == "[6 x 10^1] s"); -static_assert(unit_symbol(mag_ratio<1, 18> * metre / second) == "[1/18] m/s"); +static_assert(unit_symbol(mag<100> * metre) == "[100 m]"); +static_assert(unit_symbol(mag<100> * metre) == "[100 m]"); +static_assert(unit_symbol(mag<1000> * metre) == "[10³ m]"); +static_assert(unit_symbol(mag_power<10, 3> * metre) == "[10³ m]"); +static_assert(unit_symbol(mag<1000> * metre) == "[10^3 m]"); +static_assert(unit_symbol(mag<6000> * metre) == "[6 × 10³ m]"); +static_assert(unit_symbol(mag<6> * mag_power<10, 3> * metre) == "[6 × 10³ m]"); +static_assert(unit_symbol(mag<6000> * metre) == "[6 x 10^3 m]"); +static_assert(unit_symbol(mag<10600> * metre) == "[10600 m]"); +static_assert(unit_symbol(mag<60> * second) == "[60 s]"); +static_assert(unit_symbol(mag_ratio<1, 18> * metre / second) == "[1/18 m/s]"); +static_assert(unit_symbol(mag_ratio<1, 1800> * metre / second) == "[1/1800 m/s]"); +static_assert(unit_symbol(mag_ratio<1, 18000> * metre / second) == "[1/18 × 10⁻³ m/s]"); +static_assert(unit_symbol(mag_ratio<1, 18000> * metre / second) == + "[1/18 x 10^-3 m/s]"); // common units -static_assert(unit_symbol(get_common_unit(kilo, mile)) == "EQUIV{[1/25146] mi, [1/15625] km}"); -static_assert(unit_symbol(get_common_unit(kilo / hour, metre / second)) == "EQUIV{[1/5] km/h, [1/18] m/s}"); +static_assert(unit_symbol(get_common_unit(kilo, mile)) == "EQUIV{[1/25146 mi], [1/15625 km]}"); +static_assert(unit_symbol(get_common_unit(kilo / hour, metre / second)) == "EQUIV{[1/5 km/h], [1/18 m/s]}"); static_assert(unit_symbol(get_common_unit(kilo / hour, metre / second) / second) == - "EQUIV{[1/5] km/h, [1/18] m/s}/s"); + "EQUIV{[1/5 km/h], [1/18 m/s]}/s"); static_assert(unit_symbol(get_common_unit(kilo / hour, metre / second) * second) == - "EQUIV{[1/5] km/h, [1/18] m/s} s"); + "EQUIV{[1/5 km/h], [1/18 m/s]} s"); // derived units static_assert(unit_symbol(one) == ""); // NOLINT(readability-container-size-empty)