From 2ed0c42102856cbb2d34999a4625d39364848d7c Mon Sep 17 00:00:00 2001 From: Hammie Date: Thu, 30 Dec 2021 09:27:46 +0100 Subject: [PATCH] Fix comparing strings with raw string literals and count parameter for partial comparisons --- .../util/include/storm/string_compare.hpp | 58 ++++++++++++++++--- src/libs/util/testsuite/string_compare.cpp | 14 +++++ 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/src/libs/util/include/storm/string_compare.hpp b/src/libs/util/include/storm/string_compare.hpp index 021d8be6c..66d7ed29f 100644 --- a/src/libs/util/include/storm/string_compare.hpp +++ b/src/libs/util/include/storm/string_compare.hpp @@ -34,28 +34,72 @@ struct is_iless_eq } // namespace detail +template +bool iEquals(const Range1T &first, const Range2T &second, const size_t count) +{ + detail::is_iequal comp; + + const auto &first_normalized = std::is_pointer::value ? std::string_view(first) : first; + const auto &second_normalized = std::is_pointer::value ? std::string_view(second) : second; + + const auto first_begin = std::begin(first_normalized); + const auto second_begin = std::begin(second_normalized); + + const auto first_end = std::end(first_normalized); + const auto second_end = std::end(second_normalized); + + const auto first_length = std::distance(first_begin, first_end) - 1; + const auto second_length = std::distance(first_begin, first_end) - 1; + if (first_length < count || second_length < count) + { + if (first_length != second_length) + { + return false; + } + else + { + return std::equal(first_begin, first_begin + first_length, second_begin, second_begin + second_length, + comp); + } + } + else + { + return std::equal(first_begin, first_end, second_begin, second_end, comp); + } +} + template bool iEquals(const Range1T &first, const Range2T &second) { detail::is_iequal comp; - const auto first_begin = std::begin(first); - const auto second_begin = std::begin(second); + const auto &first_normalized = std::is_pointer::value ? std::string_view(first) : first; + const auto &second_normalized = std::is_pointer::value ? std::string_view(second) : second; + + const auto first_begin = std::begin(first_normalized); + const auto second_begin = std::begin(second_normalized); - const auto first_end = std::end(first); - const auto second_end = std::end(second); + const auto first_end = std::end(first_normalized); + const auto second_end = std::end(second_normalized); return std::equal(first_begin, first_end, second_begin, second_end, comp); } template bool iLess(const Range1T &first, const Range2T &second) { - return std::lexicographical_compare(std::begin(first), std::end(first), std::begin(second), std::end(second), - detail::is_iless{}); + const auto &first_normalized = std::is_pointer::value ? std::string_view(first) : first; + const auto &second_normalized = std::is_pointer::value ? std::string_view(second) : second; + + return std::lexicographical_compare(std::begin(first_normalized), std::end(first_normalized), + std::begin(second_normalized), std::end(second_normalized), detail::is_iless{}); } template bool iLessOrEqual(const Range1T &first, const Range2T &second) { - return std::lexicographical_compare(std::begin(first), std::end(first), std::begin(second), std::end(second), + const auto &first_normalized = std::is_pointer::value ? std::string_view(first) : first; + const auto &second_normalized = std::is_pointer::value ? std::string_view(second) : second; + + return std::lexicographical_compare(std::begin(first_normalized), std::end(first_normalized), + std::begin(second_normalized), std::end(second_normalized), detail::is_iless_eq{}); } diff --git a/src/libs/util/testsuite/string_compare.cpp b/src/libs/util/testsuite/string_compare.cpp index 4d8a115e4..ac3dca31a 100644 --- a/src/libs/util/testsuite/string_compare.cpp +++ b/src/libs/util/testsuite/string_compare.cpp @@ -45,6 +45,20 @@ TEST_CASE("Case-insensitive string comparison", "[utils]") { CHECK_FALSE(iEquals(str_lowercase, str_long)); } + + SECTION("Compare with raw char string literal") + { + CHECK(iEquals(str_lowercase, "myString")); + + const char string_array[] = "myString"; + CHECK(iEquals(string_array, str_lowercase)); + + } + + SECTION("Compare only count number of character at most") + { + CHECK(iEquals(str_lowercase, str_long, 8)); + } } SECTION("iLess")