From c3be7f0188fcebb872b9dd9876252e26f6847833 Mon Sep 17 00:00:00 2001 From: Philip Top Date: Fri, 26 May 2023 17:23:37 -0700 Subject: [PATCH 1/6] add processing for addition in unit strings --- test/test_unit_strings.cpp | 16 +++++++++++ units/units.cpp | 54 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/test/test_unit_strings.cpp b/test/test_unit_strings.cpp index 81d71916..db0b8e9c 100644 --- a/test/test_unit_strings.cpp +++ b/test/test_unit_strings.cpp @@ -1027,6 +1027,22 @@ TEST(stringToUnits, rotSequences) EXPECT_EQ(u1, unit_from_string("BTU-IT")); } +TEST(stringToUnits, addition) +{ + auto u1 = unit_from_string("cm+cm"); + EXPECT_EQ(u1, precise_unit(2,precise::cm)); + + u1 = unit_from_string("km + m+ cm+mm"); + EXPECT_EQ(u1, precise_unit(1001.011,precise::m)); + u1 = unit_from_string("kilometer+ 3in"); + EXPECT_EQ(u1, (1.0*precise::km+3.0*precise::in).as_unit()); + + u1 = unit_from_string("km+ 7.0 feet"); + EXPECT_EQ(u1, (1.0*precise::km+7.0*precise::ft).as_unit()); + u1 = unit_from_string("m*km+ ft*in"); + EXPECT_EQ(u1, (1.0*precise::km*precise::m+1.0*precise::ft*precise::in).as_unit()); +} + TEST(stringToUnits, cleanPhase2) { auto u1 = unit_from_string("tech-nical-at-mosphere"); diff --git a/units/units.cpp b/units/units.cpp index 809e1014..a97f317c 100644 --- a/units/units.cpp +++ b/units/units.cpp @@ -4795,6 +4795,52 @@ static precise_unit return precise::invalid; } +/** handle addition of similar units as a regular unit*/ +static precise_unit +checkUnitAddition(const std::string& unit_string, std::uint64_t match_flags) +{ + auto sep = findOperatorSep(unit_string, "+"); + if (sep != std::string::npos&& sep>0) { + if ((unit_string[sep - 1] == '+') || sep == unit_string.size() - 1 || unit_string[sep + 1] == '+') + { + return precise::invalid; + } + precise_unit a_unit; + precise_unit b_unit; + if (sep + 1 > unit_string.size() / 2) { + b_unit = unit_from_string_internal( + unit_string.substr(sep + 1), match_flags); + if (!is_valid(b_unit)) { + return precise::invalid; + } + a_unit = unit_from_string_internal( + unit_string.substr(0, sep), match_flags); + + if (!is_valid(a_unit)) { + return precise::invalid; + } + } else { + a_unit = unit_from_string_internal( + unit_string.substr(0, sep), match_flags); + + if (!is_valid(a_unit)) { + return precise::invalid; + } + b_unit = unit_from_string_internal( + unit_string.substr(sep + 1), match_flags); + if (!is_valid(b_unit)) { + return precise::invalid; + } + } + auto res=convert(b_unit,a_unit); + if (!std::isnan(res)) + { + return precise_unit(a_unit.base_units(),a_unit.multiplier()+a_unit.multiplier()*res); + } + } + return precise::invalid; +} + precise_unit unit_from_string(std::string unit_string, std::uint64_t match_flags) { @@ -4933,6 +4979,14 @@ static precise_unit unit_from_string_internal( return front_unit * retunit; } } + + if (unit_string.find_first_of('+') != std::string::npos) + { + retunit = checkUnitAddition(unit_string, match_flags); + if (is_valid(retunit)) { + return retunit; + } + } auto sep = findOperatorSep(unit_string, "*/"); if (sep != std::string::npos) { From 7af5bdcca3a3c4c56288e6cb1e0794213a84a5ca Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 27 May 2023 00:26:57 +0000 Subject: [PATCH 2/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- test/test_unit_strings.cpp | 13 ++++++++----- units/units.cpp | 22 +++++++++++----------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/test/test_unit_strings.cpp b/test/test_unit_strings.cpp index db0b8e9c..3c66d51c 100644 --- a/test/test_unit_strings.cpp +++ b/test/test_unit_strings.cpp @@ -1030,17 +1030,20 @@ TEST(stringToUnits, rotSequences) TEST(stringToUnits, addition) { auto u1 = unit_from_string("cm+cm"); - EXPECT_EQ(u1, precise_unit(2,precise::cm)); + EXPECT_EQ(u1, precise_unit(2, precise::cm)); u1 = unit_from_string("km + m+ cm+mm"); - EXPECT_EQ(u1, precise_unit(1001.011,precise::m)); + EXPECT_EQ(u1, precise_unit(1001.011, precise::m)); u1 = unit_from_string("kilometer+ 3in"); - EXPECT_EQ(u1, (1.0*precise::km+3.0*precise::in).as_unit()); + EXPECT_EQ(u1, (1.0 * precise::km + 3.0 * precise::in).as_unit()); u1 = unit_from_string("km+ 7.0 feet"); - EXPECT_EQ(u1, (1.0*precise::km+7.0*precise::ft).as_unit()); + EXPECT_EQ(u1, (1.0 * precise::km + 7.0 * precise::ft).as_unit()); u1 = unit_from_string("m*km+ ft*in"); - EXPECT_EQ(u1, (1.0*precise::km*precise::m+1.0*precise::ft*precise::in).as_unit()); + EXPECT_EQ( + u1, + (1.0 * precise::km * precise::m + 1.0 * precise::ft * precise::in) + .as_unit()); } TEST(stringToUnits, cleanPhase2) diff --git a/units/units.cpp b/units/units.cpp index a97f317c..3c035d16 100644 --- a/units/units.cpp +++ b/units/units.cpp @@ -4797,12 +4797,12 @@ static precise_unit /** handle addition of similar units as a regular unit*/ static precise_unit -checkUnitAddition(const std::string& unit_string, std::uint64_t match_flags) + checkUnitAddition(const std::string& unit_string, std::uint64_t match_flags) { auto sep = findOperatorSep(unit_string, "+"); - if (sep != std::string::npos&& sep>0) { - if ((unit_string[sep - 1] == '+') || sep == unit_string.size() - 1 || unit_string[sep + 1] == '+') - { + if (sep != std::string::npos && sep > 0) { + if ((unit_string[sep - 1] == '+') || sep == unit_string.size() - 1 || + unit_string[sep + 1] == '+') { return precise::invalid; } precise_unit a_unit; @@ -4832,10 +4832,11 @@ checkUnitAddition(const std::string& unit_string, std::uint64_t match_flags) return precise::invalid; } } - auto res=convert(b_unit,a_unit); - if (!std::isnan(res)) - { - return precise_unit(a_unit.base_units(),a_unit.multiplier()+a_unit.multiplier()*res); + auto res = convert(b_unit, a_unit); + if (!std::isnan(res)) { + return precise_unit( + a_unit.base_units(), + a_unit.multiplier() + a_unit.multiplier() * res); } } return precise::invalid; @@ -4979,9 +4980,8 @@ static precise_unit unit_from_string_internal( return front_unit * retunit; } } - - if (unit_string.find_first_of('+') != std::string::npos) - { + + if (unit_string.find_first_of('+') != std::string::npos) { retunit = checkUnitAddition(unit_string, match_flags); if (is_valid(retunit)) { return retunit; From 444f8707c661c7661aee7483f8394421d1c1d38d Mon Sep 17 00:00:00 2001 From: Philip Top Date: Fri, 26 May 2023 17:34:42 -0700 Subject: [PATCH 3/6] fix clang tidy warning --- units/units.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/units/units.cpp b/units/units.cpp index a97f317c..aa56dcd2 100644 --- a/units/units.cpp +++ b/units/units.cpp @@ -4835,7 +4835,7 @@ checkUnitAddition(const std::string& unit_string, std::uint64_t match_flags) auto res=convert(b_unit,a_unit); if (!std::isnan(res)) { - return precise_unit(a_unit.base_units(),a_unit.multiplier()+a_unit.multiplier()*res); + return { a_unit.base_units(),a_unit.multiplier() + a_unit.multiplier() * res }; } } return precise::invalid; From 38a33c709339b68bc32d3106e1aa36ac7cf5aa2d Mon Sep 17 00:00:00 2001 From: Philip Top Date: Fri, 26 May 2023 19:54:02 -0700 Subject: [PATCH 4/6] add more tests for coverage --- test/test_unit_strings.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/test_unit_strings.cpp b/test/test_unit_strings.cpp index 3c66d51c..3e1e490d 100644 --- a/test/test_unit_strings.cpp +++ b/test/test_unit_strings.cpp @@ -1044,6 +1044,15 @@ TEST(stringToUnits, addition) u1, (1.0 * precise::km * precise::m + 1.0 * precise::ft * precise::in) .as_unit()); + + u1=unit_from_string("meter + hippyhoppy"); + EXPECT_FALSE(is_valid(u1)); + + u1=unit_from_string("hippyhoppy + meter"); + EXPECT_FALSE(is_valid(u1)); + + u1= unit_from_string("meter + kg"); + EXPECT_EQ(u1, precise::m*precise::kg); } TEST(stringToUnits, cleanPhase2) From 5a6a3320a17fb989e2cfb0fd7098bba9c885ce93 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 27 May 2023 02:54:24 +0000 Subject: [PATCH 5/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- test/test_unit_strings.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_unit_strings.cpp b/test/test_unit_strings.cpp index 3e1e490d..45a0b6d4 100644 --- a/test/test_unit_strings.cpp +++ b/test/test_unit_strings.cpp @@ -1045,14 +1045,14 @@ TEST(stringToUnits, addition) (1.0 * precise::km * precise::m + 1.0 * precise::ft * precise::in) .as_unit()); - u1=unit_from_string("meter + hippyhoppy"); + u1 = unit_from_string("meter + hippyhoppy"); EXPECT_FALSE(is_valid(u1)); - u1=unit_from_string("hippyhoppy + meter"); + u1 = unit_from_string("hippyhoppy + meter"); EXPECT_FALSE(is_valid(u1)); - u1= unit_from_string("meter + kg"); - EXPECT_EQ(u1, precise::m*precise::kg); + u1 = unit_from_string("meter + kg"); + EXPECT_EQ(u1, precise::m * precise::kg); } TEST(stringToUnits, cleanPhase2) From ef72d12508415a5dacf9a90e3eff52ccb5a574f5 Mon Sep 17 00:00:00 2001 From: Philip Top Date: Sat, 27 May 2023 05:33:25 -0700 Subject: [PATCH 6/6] add more tests for coverage --- .codecov.yml | 2 +- test/test_unit_strings.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.codecov.yml b/.codecov.yml index 199f18c9..274b396a 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -7,7 +7,7 @@ codecov: coverage: precision: 2 round: down - range: '90...100' + range: '95...100' status: project: default: diff --git a/test/test_unit_strings.cpp b/test/test_unit_strings.cpp index 45a0b6d4..096a6147 100644 --- a/test/test_unit_strings.cpp +++ b/test/test_unit_strings.cpp @@ -1051,6 +1051,12 @@ TEST(stringToUnits, addition) u1 = unit_from_string("hippyhoppy + meter"); EXPECT_FALSE(is_valid(u1)); + u1 = unit_from_string("arggh + kilometer"); + EXPECT_FALSE(is_valid(u1)); + + u1 = unit_from_string("kilometer + arggh"); + EXPECT_FALSE(is_valid(u1)); + u1 = unit_from_string("meter + kg"); EXPECT_EQ(u1, precise::m * precise::kg); }