aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/case_insensitive_string/case_insensitive_char_traits.h
diff options
context:
space:
mode:
authorvadim-xd <vadim-xd@yandex-team.com>2024-06-09 14:29:51 +0300
committervadim-xd <vadim-xd@yandex-team.com>2024-06-09 14:38:13 +0300
commit22d59c45d8f17195622bd9e5bfa9259c50b1a732 (patch)
tree508002f84f703be6d6f92443827d1a4e255d457f /library/cpp/case_insensitive_string/case_insensitive_char_traits.h
parentafd4899380eea1c70e2a68714b5da1c9919ccdbd (diff)
downloadydb-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.h55
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);
+ }
+};