From cbf8e3412f6258514a716b093526b48f3222a57c Mon Sep 17 00:00:00 2001 From: technateNG Date: Fri, 10 Jan 2020 06:55:47 +0000 Subject: [PATCH] perf: Added utilities::caseInsensitiveLess. (#882) * Added utilities::caseInsensitiveLess to compare two wstring arguments * Replaced less comparision method in DummyNodeComp. * Added tests for caseInsensitiveLess. --- .../component/controller/helper/DummyNode.h | 2 +- src/lib_utility/utility/utilityString.cpp | 23 +++++++ src/lib_utility/utility/utilityString.h | 2 + src/test/UtilityStringTestSuite.cpp | 66 +++++++++++++++++++ 4 files changed, 92 insertions(+), 1 deletion(-) diff --git a/src/lib/component/controller/helper/DummyNode.h b/src/lib/component/controller/helper/DummyNode.h index e2c9af09..ca9f08cd 100644 --- a/src/lib/component/controller/helper/DummyNode.h +++ b/src/lib/component/controller/helper/DummyNode.h @@ -40,7 +40,7 @@ public: return a->isBundleNode(); } - return utility::toLowerCase(a->name) < utility::toLowerCase(b->name); + return utility::caseInsensitiveLess(a->name, b->name); } }; diff --git a/src/lib_utility/utility/utilityString.cpp b/src/lib_utility/utility/utilityString.cpp index 2fed84c9..19604878 100644 --- a/src/lib_utility/utility/utilityString.cpp +++ b/src/lib_utility/utility/utilityString.cpp @@ -622,4 +622,27 @@ std::wstring convertWhiteSpacesToSingleSpaces(const std::wstring& str) return join>(parts, L" "); } + +bool caseInsensitiveLess(const std::wstring& s1, const std::wstring& s2) +{ + size_t s1_size = s1.size(); + size_t s2_size = s2.size(); + bool res_cmp = s1_size < s2_size; + size_t lesser_size = s2_size ^ ((s1_size ^ s2_size) & -res_cmp); + for (size_t i = 0; i < lesser_size; ++i) + { + wchar_t s1_wchr = s1[i]; + wchar_t s2_wchr = s2[i]; + if (s1_wchr != s2_wchr) + { + s1_wchr = towlower(s1_wchr); + s2_wchr = towlower(s2_wchr); + if (s1_wchr != s2_wchr) + { + return s1_wchr < s2_wchr; + } + } + } + return res_cmp; +} } // namespace utility diff --git a/src/lib_utility/utility/utilityString.h b/src/lib_utility/utility/utilityString.h index 4d360fcf..7e9716ef 100644 --- a/src/lib_utility/utility/utilityString.h +++ b/src/lib_utility/utility/utilityString.h @@ -99,6 +99,8 @@ std::wstring elide(const std::wstring& str, ElideMode mode, size_t size); std::wstring convertWhiteSpacesToSingleSpaces(const std::wstring& str); +bool caseInsensitiveLess(const std::wstring& s1, const std::wstring& s2); + template ContainerType split(const std::string& str, const std::string& delimiter) { diff --git a/src/test/UtilityStringTestSuite.cpp b/src/test/UtilityStringTestSuite.cpp index fc53c582..e9574d78 100644 --- a/src/test/UtilityStringTestSuite.cpp +++ b/src/test/UtilityStringTestSuite.cpp @@ -300,3 +300,69 @@ TEST_CASE("replace") REQUIRE("" == utility::replace("", "foo", "bar")); REQUIRE("foobar" == utility::replace("foobar", "ba", "ba")); } + +TEST_CASE("caseInsensitiveLess should return false when comparing empty wstrings") +{ + REQUIRE_FALSE(utility::caseInsensitiveLess(L"", L"")); +} + +TEST_CASE("caseInsensitiveLess should return false when both wstrings are equal") +{ + REQUIRE_FALSE(utility::caseInsensitiveLess(L"ab_cd!", L"ab_cd!")); +} + +TEST_CASE("caseInsensitiveLess should return false when both wstrings have" + "different cases but after lower casing are equal") +{ + REQUIRE_FALSE(utility::caseInsensitiveLess(L"ab_CD!", L"aB_cD!")); +} + +TEST_CASE("caseInsensitiveLess should return true when first wstring is empty and second not") +{ + REQUIRE(utility::caseInsensitiveLess(L"", L"ab")); +} + +TEST_CASE("caseInsensitiveLess should return false when second wstring is empty and first not") +{ + REQUIRE_FALSE(utility::caseInsensitiveLess(L"ab", L"")); +} + +TEST_CASE("caseInsensitiveLess should return true when first wstring is prefix of second") +{ + REQUIRE(utility::caseInsensitiveLess(L"ab_cd!", L"ab_cd!e")); +} + +TEST_CASE("caseInsensitiveLess should return false when second wstring is prefix of first") +{ + REQUIRE_FALSE(utility::caseInsensitiveLess(L"ab_cd!e", L"ab_cd!")); +} + +TEST_CASE("caseInsensitiveLess should return true when after lower casing first wstring, first is prefix of second") +{ + REQUIRE(utility::caseInsensitiveLess(L"aB_cd!", L"ab_cd!e")); +} + +TEST_CASE("caseInsensitiveLess should return true when after lower casing second wstring, first is prefix of second") +{ + REQUIRE(utility::caseInsensitiveLess(L"ab_cd!", L"ab_cD!e")); +} + +TEST_CASE("caseInsensitiveLess should return true when after lower casing both wstrings, first is prefix of second") +{ + REQUIRE(utility::caseInsensitiveLess(L"aB_cd!", L"ab_cD!E")); +} + +TEST_CASE("caseInsensitiveLess should return false when after lower casing first wstring, second is prefix of first") +{ + REQUIRE_FALSE(utility::caseInsensitiveLess(L"ab_Cd!e", L"ab_cd!")); +} + +TEST_CASE("caseInsensitiveLess should return false when after lower casing second wstring, second is prefix of first") +{ + REQUIRE_FALSE(utility::caseInsensitiveLess(L"ab_cd!e", L"Ab_cd!")); +} + +TEST_CASE("caseInsensitiveLess should return false when after lower casing both wstrings, second is prefix of first") +{ + REQUIRE_FALSE(utility::caseInsensitiveLess(L"ab_cD!E", L"aB_cd!")); +}