diff options
author | vadim-xd <vadim-xd@yandex-team.com> | 2024-06-09 14:29:51 +0300 |
---|---|---|
committer | vadim-xd <vadim-xd@yandex-team.com> | 2024-06-09 14:38:13 +0300 |
commit | 22d59c45d8f17195622bd9e5bfa9259c50b1a732 (patch) | |
tree | 508002f84f703be6d6f92443827d1a4e255d457f /library/cpp/case_insensitive_string/case_insensitive_char_traits.h | |
parent | afd4899380eea1c70e2a68714b5da1c9919ccdbd (diff) | |
download | ydb-22d59c45d8f17195622bd9e5bfa9259c50b1a732.tar.gz |
Add TCaseInsensitiveAsciiString
Followup for rXXXXXX - further optimize ascii-only case insensitive strings
1fca7889a074a191eadce12247bdd6dd18b75ab2
Diffstat (limited to 'library/cpp/case_insensitive_string/case_insensitive_char_traits.h')
-rw-r--r-- | library/cpp/case_insensitive_string/case_insensitive_char_traits.h | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/library/cpp/case_insensitive_string/case_insensitive_char_traits.h b/library/cpp/case_insensitive_string/case_insensitive_char_traits.h index 2717893c10..fdf5f3a6c0 100644 --- a/library/cpp/case_insensitive_string/case_insensitive_char_traits.h +++ b/library/cpp/case_insensitive_string/case_insensitive_char_traits.h @@ -2,29 +2,54 @@ #include <contrib/libs/libc_compat/string.h> +#include <util/string/ascii.h> + #include <string> -struct TCaseInsensitiveCharTraits : private std::char_traits<char> { - static bool eq(char c1, char c2) { - return to_upper(c1) == to_upper(c2); - } +namespace NPrivate { + template <typename TImpl> + struct TCommonCaseInsensitiveCharTraits : private std::char_traits<char> { + static bool eq(char c1, char c2) { + return TImpl::ToCommonCase(c1) == TImpl::ToCommonCase(c2); + } - static bool lt(char c1, char c2) { - return to_upper(c1) < to_upper(c2); - } + static bool lt(char c1, char c2) { + return TImpl::ToCommonCase(c1) < TImpl::ToCommonCase(c2); + } - static int compare(const char* s1, const char* s2, std::size_t n); + static const char* find(const char* s, std::size_t n, char a); - static const char* find(const char* s, std::size_t n, char a); + using std::char_traits<char>::assign; + using std::char_traits<char>::char_type; + using std::char_traits<char>::copy; + using std::char_traits<char>::length; + using std::char_traits<char>::move; + }; +} // namespace NPrivate - using std::char_traits<char>::assign; - using std::char_traits<char>::char_type; - using std::char_traits<char>::copy; - using std::char_traits<char>::length; - using std::char_traits<char>::move; +struct TCaseInsensitiveCharTraits : public ::NPrivate::TCommonCaseInsensitiveCharTraits<TCaseInsensitiveCharTraits> { + static int compare(const char* s1, const char* s2, std::size_t n); private: - static char to_upper(char ch) { + friend ::NPrivate::TCommonCaseInsensitiveCharTraits<TCaseInsensitiveCharTraits>; + + // XXX return unsigned char. Current impl depends on char signedness, and if char is signed, + // TCaseInsensitiveCharTraits::compare returns different result from std::char_traits<char>::compare for non-ascii strings. + static char ToCommonCase(char ch) { return std::toupper((unsigned char)ch); } }; + +struct TCaseInsensitiveAsciiCharTraits : public ::NPrivate::TCommonCaseInsensitiveCharTraits<TCaseInsensitiveCharTraits> { + // WARN: does not work with null bytes (`compare("ab\0c", "ab\0d", 4)` returns 0). + static int compare(const char* s1, const char* s2, std::size_t n) { + return ::strncasecmp(s1, s2, n); + } + +private: + friend ::NPrivate::TCommonCaseInsensitiveCharTraits<TCaseInsensitiveAsciiCharTraits>; + + static unsigned char ToCommonCase(char ch) { + return AsciiToLower(ch); + } +}; |