From 834d1fa09d2e93197ac5d9b053aa5fad999e36b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20Sch=C3=B6nrock?= Date: Thu, 20 Feb 2020 22:15:05 +0000 Subject: [PATCH] extending the range of operator* for incoherent units with large num/den this improves the situation for #55 (doesn't solve it outright) motivating examples which now work are: 1q_mi * 1q_mi * 1q_mi 1q_au * 1q_au tests added and docs updated --- doc/DESIGN.md | 2 +- src/include/units/bits/external/text_tools.h | 10 +++++----- src/include/units/concepts.h | 2 +- test/unit_test/runtime/fmt_units_test.cpp | 6 ++++++ 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/doc/DESIGN.md b/doc/DESIGN.md index 535c6740..b19bee64 100644 --- a/doc/DESIGN.md +++ b/doc/DESIGN.md @@ -78,7 +78,7 @@ where: ```cpp template -concept UnitRatio = Ratio && (R::num * R::den > 0); +concept UnitRatio = Ratio && R::num > 0 && R::den > 0; // double negatives not allowed ``` and `Ratio` is satisfied by any instantiation of `units::ratio`. diff --git a/src/include/units/bits/external/text_tools.h b/src/include/units/bits/external/text_tools.h index aa6f9a03..aabf37a5 100644 --- a/src/include/units/bits/external/text_tools.h +++ b/src/include/units/bits/external/text_tools.h @@ -26,7 +26,7 @@ namespace units::detail { -template +template requires (0 <= Value) && (Value < 10) inline constexpr basic_fixed_string superscript_number = ""; @@ -43,7 +43,7 @@ template<> inline constexpr basic_fixed_string superscript_number<9> = "\u2079"; inline constexpr basic_fixed_string superscript_minus = "\u207b"; -template +template constexpr auto superscript() { if constexpr(Value < 0) @@ -54,12 +54,12 @@ constexpr auto superscript() return superscript() + superscript(); } -template +template constexpr auto regular() { - if constexpr(Value < 0) + if constexpr (Value < 0) return basic_fixed_string("-") + superscript<-Value>(); - else if constexpr(Value < 10) + else if constexpr (Value < 10) return basic_fixed_string(static_cast('0' + Value)); else return regular() + regular(); diff --git a/src/include/units/concepts.h b/src/include/units/concepts.h index 11714e22..8bb3e666 100644 --- a/src/include/units/concepts.h +++ b/src/include/units/concepts.h @@ -79,7 +79,7 @@ concept Ratio = detail::is_ratio; // UnitRatio template -concept UnitRatio = Ratio && (R::num * R::den > 0); +concept UnitRatio = Ratio && R::num > 0 && R::den > 0; // double negatives not allowed // Unit template diff --git a/test/unit_test/runtime/fmt_units_test.cpp b/test/unit_test/runtime/fmt_units_test.cpp index bf43b9f2..31291cef 100644 --- a/test/unit_test/runtime/fmt_units_test.cpp +++ b/test/unit_test/runtime/fmt_units_test.cpp @@ -175,4 +175,10 @@ TEST_CASE("fmt::format on synthesized unit symbols", "[text][fmt]") { CHECK(fmt::format("{}", 1q_in + 1q_yd) == "37 in"); } + + SECTION("incoherent units with powers") + { + CHECK(fmt::format("{}", 1q_mi * 1q_mi * 1q_mi) == "1 [15900351812136/3814697265625 × 10⁹] m³"); + CHECK(fmt::format("{}", 1q_au * 1q_au) == "1 [2237952291797391849 × 10⁴] m²"); + } }