diff --git a/src/Utils/Utils/StringUtils.cpp b/src/Utils/Utils/StringUtils.cpp index 5328ccaa..3f885a86 100644 --- a/src/Utils/Utils/StringUtils.cpp +++ b/src/Utils/Utils/StringUtils.cpp @@ -4,14 +4,6 @@ #include #include -namespace -{ - bool ichar_equals(const char a, const char b) - { - return std::tolower(static_cast(a)) == std::tolower(static_cast(b)); - } -} // namespace - namespace utils { std::string EscapeStringForQuotationMarks(const std::string_view& str) @@ -123,11 +115,6 @@ namespace utils c = static_cast(toupper(static_cast(c))); } - bool StringEqualsIgnoreCase(std::string_view lhs, std::string_view rhs) - { - return std::ranges::equal(lhs, rhs, ichar_equals); - } - void StringTrimL(std::string& str) { str.erase(str.begin(), diff --git a/src/Utils/Utils/StringUtils.h b/src/Utils/Utils/StringUtils.h index bcee2731..8bf7e792 100644 --- a/src/Utils/Utils/StringUtils.h +++ b/src/Utils/Utils/StringUtils.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -20,7 +21,20 @@ namespace utils void MakeStringUpperCase(char* str); void MakeStringUpperCase(std::string& str); - bool StringEqualsIgnoreCase(std::string_view lhs, std::string_view rhs); + constexpr char CharToLowerAscii(const char c) + { + return c >= 'A' && c <= 'Z' ? static_cast(c - 'A' + 'a') : c; + } + + constexpr bool StringEqualsIgnoreCase(const std::string_view lhs, const std::string_view rhs) + { + return std::ranges::equal(lhs, + rhs, + [](const char a, const char b) + { + return CharToLowerAscii(a) == CharToLowerAscii(b); + }); + } void StringTrimL(std::string& str); void StringTrimR(std::string& str); diff --git a/test/CommonTests/Utils/StringUtilsTests.cpp b/test/CommonTests/Utils/StringUtilsTests.cpp new file mode 100644 index 00000000..e434213e --- /dev/null +++ b/test/CommonTests/Utils/StringUtilsTests.cpp @@ -0,0 +1,23 @@ +#include "Utils/StringUtils.h" + +#include + +static_assert(utils::StringEqualsIgnoreCase("", "")); +static_assert(utils::StringEqualsIgnoreCase("Hello World", "hELLO wORLD")); +static_assert(!utils::StringEqualsIgnoreCase("Hello", "Hello World")); +static_assert(!utils::StringEqualsIgnoreCase("[", "{")); + +TEST_CASE("StringUtils: StringEqualsIgnoreCase", "[stringutils]") +{ + SECTION("matches strings that only differ in case") + { + REQUIRE(utils::StringEqualsIgnoreCase("mp_rust", "MP_Rust")); + REQUIRE(utils::StringEqualsIgnoreCase("ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")); + } + + SECTION("does not match different strings") + { + REQUIRE_FALSE(utils::StringEqualsIgnoreCase("mp_rust", "mp_rust2")); + REQUIRE_FALSE(utils::StringEqualsIgnoreCase("@", "`")); + } +}