summaryrefslogtreecommitdiff
path: root/core/fxcrt
diff options
context:
space:
mode:
Diffstat (limited to 'core/fxcrt')
-rw-r--r--core/fxcrt/bytestring.cpp50
-rw-r--r--core/fxcrt/bytestring.h7
-rw-r--r--core/fxcrt/bytestring_unittest.cpp95
-rw-r--r--core/fxcrt/string_view_template.h5
-rw-r--r--core/fxcrt/widestring.cpp67
-rw-r--r--core/fxcrt/widestring.h7
-rw-r--r--core/fxcrt/widestring_unittest.cpp95
7 files changed, 284 insertions, 42 deletions
diff --git a/core/fxcrt/bytestring.cpp b/core/fxcrt/bytestring.cpp
index 37121a7da9..704cdd46aa 100644
--- a/core/fxcrt/bytestring.cpp
+++ b/core/fxcrt/bytestring.cpp
@@ -251,13 +251,39 @@ bool ByteString::operator==(const ByteString& other) const {
m_pData->m_nDataLength) == 0;
}
-bool ByteString::operator<(const ByteString& str) const {
- if (m_pData == str.m_pData)
+bool ByteString::operator<(const char* ptr) const {
+ if (!m_pData && !ptr)
return false;
+ if (c_str() == ptr)
+ return false;
+
+ size_t len = GetLength();
+ size_t other_len = ptr ? strlen(ptr) : 0;
+ int result = memcmp(c_str(), ptr, std::min(len, other_len));
+ return result < 0 || (result == 0 && len < other_len);
+}
+bool ByteString::operator<(const ByteStringView& str) const {
+ if (!m_pData && !str.unterminated_c_str())
+ return false;
+ if (c_str() == str.unterminated_c_str())
+ return false;
+
+ size_t len = GetLength();
+ size_t other_len = str.GetLength();
int result =
- memcmp(c_str(), str.c_str(), std::min(GetLength(), str.GetLength()));
- return result < 0 || (result == 0 && GetLength() < str.GetLength());
+ memcmp(c_str(), str.unterminated_c_str(), std::min(len, other_len));
+ return result < 0 || (result == 0 && len < other_len);
+}
+
+bool ByteString::operator<(const ByteString& other) const {
+ if (m_pData == other.m_pData)
+ return false;
+
+ size_t len = GetLength();
+ size_t other_len = other.GetLength();
+ int result = memcmp(c_str(), other.c_str(), std::min(len, other_len));
+ return result < 0 || (result == 0 && len < other_len);
}
bool ByteString::EqualNoCase(const ByteStringView& str) const {
@@ -668,26 +694,22 @@ ByteString ByteString::FromUnicode(const WideString& str) {
}
int ByteString::Compare(const ByteStringView& str) const {
- if (!m_pData) {
+ if (!m_pData)
return str.IsEmpty() ? 0 : -1;
- }
+
size_t this_len = m_pData->m_nDataLength;
size_t that_len = str.GetLength();
size_t min_len = std::min(this_len, that_len);
for (size_t i = 0; i < min_len; i++) {
- if (static_cast<uint8_t>(m_pData->m_String[i]) < str[i]) {
+ if (static_cast<uint8_t>(m_pData->m_String[i]) < str[i])
return -1;
- }
- if (static_cast<uint8_t>(m_pData->m_String[i]) > str[i]) {
+ if (static_cast<uint8_t>(m_pData->m_String[i]) > str[i])
return 1;
- }
}
- if (this_len < that_len) {
+ if (this_len < that_len)
return -1;
- }
- if (this_len > that_len) {
+ if (this_len > that_len)
return 1;
- }
return 0;
}
diff --git a/core/fxcrt/bytestring.h b/core/fxcrt/bytestring.h
index 67fdd1d9ac..6d5843efcd 100644
--- a/core/fxcrt/bytestring.h
+++ b/core/fxcrt/bytestring.h
@@ -110,7 +110,9 @@ class ByteString {
bool operator!=(const ByteStringView& str) const { return !(*this == str); }
bool operator!=(const ByteString& other) const { return !(*this == other); }
- bool operator<(const ByteString& str) const;
+ bool operator<(const char* ptr) const;
+ bool operator<(const ByteStringView& str) const;
+ bool operator<(const ByteString& other) const;
const ByteString& operator=(const char* str);
const ByteString& operator=(const ByteStringView& bstrc);
@@ -209,6 +211,9 @@ inline bool operator!=(const char* lhs, const ByteString& rhs) {
inline bool operator!=(const ByteStringView& lhs, const ByteString& rhs) {
return rhs != lhs;
}
+inline bool operator<(const char* lhs, const ByteString& rhs) {
+ return rhs.Compare(lhs) > 0;
+}
inline ByteString operator+(const ByteStringView& str1,
const ByteStringView& str2) {
diff --git a/core/fxcrt/bytestring_unittest.cpp b/core/fxcrt/bytestring_unittest.cpp
index 9812367fe8..4668fe1cc8 100644
--- a/core/fxcrt/bytestring_unittest.cpp
+++ b/core/fxcrt/bytestring_unittest.cpp
@@ -55,29 +55,94 @@ TEST(ByteString, OperatorLT) {
ByteString a("a");
ByteString abc("abc");
ByteString def("def");
+ ByteStringView v_empty;
+ ByteStringView v_a("a");
+ ByteStringView v_abc("abc");
+ ByteStringView v_def("def");
+ const char* const c_null = nullptr;
+ const char* const c_empty = "";
+ const char* const c_a = "a";
+ const char* const c_abc = "abc";
+ const char* const c_def = "def";
EXPECT_FALSE(empty < empty);
EXPECT_FALSE(a < a);
EXPECT_FALSE(abc < abc);
EXPECT_FALSE(def < def);
+ EXPECT_FALSE(c_null < empty);
+ EXPECT_FALSE(c_empty < empty);
+ EXPECT_FALSE(c_a < a);
+ EXPECT_FALSE(c_abc < abc);
+ EXPECT_FALSE(c_def < def);
+ EXPECT_FALSE(empty < c_null);
+ EXPECT_FALSE(empty < c_empty);
+ EXPECT_FALSE(a < c_a);
+ EXPECT_FALSE(abc < c_abc);
+ EXPECT_FALSE(def < c_def);
+ EXPECT_FALSE(empty < v_empty);
+ EXPECT_FALSE(a < v_a);
+ EXPECT_FALSE(abc < v_abc);
+ EXPECT_FALSE(def < v_def);
EXPECT_TRUE(empty < a);
EXPECT_FALSE(a < empty);
+ EXPECT_TRUE(c_null < a);
+ EXPECT_TRUE(c_empty < a);
+ EXPECT_FALSE(c_a < empty);
+ EXPECT_TRUE(empty < c_a);
+ EXPECT_FALSE(a < c_null);
+ EXPECT_FALSE(a < c_empty);
+ EXPECT_TRUE(empty < v_a);
+ EXPECT_FALSE(a < v_empty);
EXPECT_TRUE(empty < abc);
EXPECT_FALSE(abc < empty);
+ EXPECT_TRUE(c_null < abc);
+ EXPECT_TRUE(c_empty < abc);
+ EXPECT_FALSE(c_abc < empty);
+ EXPECT_TRUE(empty < c_abc);
+ EXPECT_FALSE(abc < c_null);
+ EXPECT_FALSE(abc < c_empty);
+ EXPECT_TRUE(empty < v_abc);
+ EXPECT_FALSE(abc < v_empty);
EXPECT_TRUE(empty < def);
EXPECT_FALSE(def < empty);
+ EXPECT_TRUE(c_null < def);
+ EXPECT_TRUE(c_empty < def);
+ EXPECT_FALSE(c_def < empty);
+ EXPECT_TRUE(empty < c_def);
+ EXPECT_FALSE(def < c_null);
+ EXPECT_FALSE(def < c_empty);
+ EXPECT_TRUE(empty < v_def);
+ EXPECT_FALSE(def < v_empty);
EXPECT_TRUE(a < abc);
EXPECT_FALSE(abc < a);
+ EXPECT_TRUE(c_a < abc);
+ EXPECT_FALSE(c_abc < a);
+ EXPECT_TRUE(a < c_abc);
+ EXPECT_FALSE(abc < c_a);
+ EXPECT_TRUE(a < v_abc);
+ EXPECT_FALSE(abc < v_a);
EXPECT_TRUE(a < def);
EXPECT_FALSE(def < a);
+ EXPECT_TRUE(c_a < def);
+ EXPECT_FALSE(c_def < a);
+ EXPECT_TRUE(a < c_def);
+ EXPECT_FALSE(def < c_a);
+ EXPECT_TRUE(a < v_def);
+ EXPECT_FALSE(def < v_a);
EXPECT_TRUE(abc < def);
EXPECT_FALSE(def < abc);
+ EXPECT_TRUE(c_abc < def);
+ EXPECT_FALSE(c_def < abc);
+ EXPECT_TRUE(abc < c_def);
+ EXPECT_FALSE(def < c_abc);
+ EXPECT_TRUE(abc < v_def);
+ EXPECT_FALSE(def < v_abc);
}
TEST(ByteString, OperatorEQ) {
@@ -1092,29 +1157,59 @@ TEST(ByteStringView, OperatorLT) {
ByteStringView a("a");
ByteStringView abc("abc");
ByteStringView def("def");
+ const char* const c_null = nullptr;
+ const char* const c_empty = "";
+ const char* const c_a = "a";
+ const char* const c_abc = "abc";
+ const char* const c_def = "def";
EXPECT_FALSE(empty < empty);
EXPECT_FALSE(a < a);
EXPECT_FALSE(abc < abc);
EXPECT_FALSE(def < def);
+ EXPECT_FALSE(c_null < empty);
+ EXPECT_FALSE(c_empty < empty);
+ EXPECT_FALSE(c_a < a);
+ EXPECT_FALSE(c_abc < abc);
+ EXPECT_FALSE(c_def < def);
+ EXPECT_FALSE(empty < c_null);
+ EXPECT_FALSE(empty < c_empty);
+ EXPECT_FALSE(a < c_a);
+ EXPECT_FALSE(abc < c_abc);
+ EXPECT_FALSE(def < c_def);
EXPECT_TRUE(empty < a);
EXPECT_FALSE(a < empty);
+ EXPECT_TRUE(empty < c_a);
+ EXPECT_FALSE(a < c_null);
+ EXPECT_FALSE(a < c_empty);
EXPECT_TRUE(empty < abc);
EXPECT_FALSE(abc < empty);
+ EXPECT_TRUE(empty < c_abc);
+ EXPECT_FALSE(abc < c_null);
+ EXPECT_FALSE(abc < c_empty);
EXPECT_TRUE(empty < def);
EXPECT_FALSE(def < empty);
+ EXPECT_TRUE(empty < c_def);
+ EXPECT_FALSE(def < c_null);
+ EXPECT_FALSE(def < c_empty);
EXPECT_TRUE(a < abc);
EXPECT_FALSE(abc < a);
+ EXPECT_TRUE(a < c_abc);
+ EXPECT_FALSE(abc < c_a);
EXPECT_TRUE(a < def);
EXPECT_FALSE(def < a);
+ EXPECT_TRUE(a < c_def);
+ EXPECT_FALSE(def < c_a);
EXPECT_TRUE(abc < def);
EXPECT_FALSE(def < abc);
+ EXPECT_TRUE(abc < c_def);
+ EXPECT_FALSE(def < c_abc);
}
TEST(ByteStringView, OperatorEQ) {
diff --git a/core/fxcrt/string_view_template.h b/core/fxcrt/string_view_template.h
index 346e5a469d..ac376ff8a0 100644
--- a/core/fxcrt/string_view_template.h
+++ b/core/fxcrt/string_view_template.h
@@ -227,11 +227,14 @@ template <typename T>
inline bool operator==(const T* lhs, const StringViewTemplate<T>& rhs) {
return rhs == lhs;
}
-
template <typename T>
inline bool operator!=(const T* lhs, const StringViewTemplate<T>& rhs) {
return rhs != lhs;
}
+template <typename T>
+inline bool operator<(const T* lhs, const StringViewTemplate<T>& rhs) {
+ return rhs > lhs;
+}
extern template class StringViewTemplate<char>;
extern template class StringViewTemplate<wchar_t>;
diff --git a/core/fxcrt/widestring.cpp b/core/fxcrt/widestring.cpp
index adeb28cc16..bd504e0cac 100644
--- a/core/fxcrt/widestring.cpp
+++ b/core/fxcrt/widestring.cpp
@@ -434,13 +434,39 @@ bool WideString::operator==(const WideString& other) const {
m_pData->m_nDataLength) == 0;
}
-bool WideString::operator<(const WideString& str) const {
- if (m_pData == str.m_pData)
+bool WideString::operator<(const wchar_t* ptr) const {
+ if (!m_pData && !ptr)
return false;
+ if (c_str() == ptr)
+ return false;
+
+ size_t len = GetLength();
+ size_t other_len = ptr ? wcslen(ptr) : 0;
+ int result = wmemcmp(c_str(), ptr, std::min(len, other_len));
+ return result < 0 || (result == 0 && len < other_len);
+}
+bool WideString::operator<(const WideStringView& str) const {
+ if (!m_pData && !str.unterminated_c_str())
+ return false;
+ if (c_str() == str.unterminated_c_str())
+ return false;
+
+ size_t len = GetLength();
+ size_t other_len = str.GetLength();
int result =
- wmemcmp(c_str(), str.c_str(), std::min(GetLength(), str.GetLength()));
- return result < 0 || (result == 0 && GetLength() < str.GetLength());
+ wmemcmp(c_str(), str.unterminated_c_str(), std::min(len, other_len));
+ return result < 0 || (result == 0 && len < other_len);
+}
+
+bool WideString::operator<(const WideString& other) const {
+ if (m_pData == other.m_pData)
+ return false;
+
+ size_t len = GetLength();
+ size_t other_len = other.GetLength();
+ int result = wmemcmp(c_str(), other.c_str(), std::min(len, other_len));
+ return result < 0 || (result == 0 && len < other_len);
}
void WideString::AssignCopy(const wchar_t* pSrcData, size_t nSrcLen) {
@@ -880,45 +906,36 @@ void WideString::SetAt(size_t index, wchar_t c) {
int WideString::Compare(const wchar_t* lpsz) const {
if (m_pData)
- return wcscmp(m_pData->m_String, lpsz);
+ return lpsz ? wcscmp(m_pData->m_String, lpsz) : 1;
return (!lpsz || lpsz[0] == 0) ? 0 : -1;
}
int WideString::Compare(const WideString& str) const {
- if (!m_pData) {
- if (!str.m_pData) {
- return 0;
- }
- return -1;
- }
- if (!str.m_pData) {
+ if (!m_pData)
+ return str.m_pData ? -1 : 0;
+ if (!str.m_pData)
return 1;
- }
+
size_t this_len = m_pData->m_nDataLength;
size_t that_len = str.m_pData->m_nDataLength;
size_t min_len = std::min(this_len, that_len);
for (size_t i = 0; i < min_len; i++) {
- if (m_pData->m_String[i] < str.m_pData->m_String[i]) {
+ if (m_pData->m_String[i] < str.m_pData->m_String[i])
return -1;
- }
- if (m_pData->m_String[i] > str.m_pData->m_String[i]) {
+ if (m_pData->m_String[i] > str.m_pData->m_String[i])
return 1;
- }
}
- if (this_len < that_len) {
+ if (this_len < that_len)
return -1;
- }
- if (this_len > that_len) {
+ if (this_len > that_len)
return 1;
- }
return 0;
}
int WideString::CompareNoCase(const wchar_t* lpsz) const {
- if (!m_pData) {
- return (!lpsz || lpsz[0] == 0) ? 0 : -1;
- }
- return FXSYS_wcsicmp(m_pData->m_String, lpsz);
+ if (m_pData)
+ return lpsz ? FXSYS_wcsicmp(m_pData->m_String, lpsz) : 1;
+ return (!lpsz || lpsz[0] == 0) ? 0 : -1;
}
size_t WideString::WStringLength(const unsigned short* str) {
diff --git a/core/fxcrt/widestring.h b/core/fxcrt/widestring.h
index 745fa5b2ab..01c4eedaf1 100644
--- a/core/fxcrt/widestring.h
+++ b/core/fxcrt/widestring.h
@@ -114,7 +114,9 @@ class WideString {
bool operator!=(const WideStringView& str) const { return !(*this == str); }
bool operator!=(const WideString& other) const { return !(*this == other); }
- bool operator<(const WideString& str) const;
+ bool operator<(const wchar_t* ptr) const;
+ bool operator<(const WideStringView& str) const;
+ bool operator<(const WideString& other) const;
CharType operator[](const size_t index) const {
ASSERT(IsValidIndex(index));
@@ -247,6 +249,9 @@ inline bool operator!=(const wchar_t* lhs, const WideString& rhs) {
inline bool operator!=(const WideStringView& lhs, const WideString& rhs) {
return rhs != lhs;
}
+inline bool operator<(const wchar_t* lhs, const WideString& rhs) {
+ return rhs.Compare(lhs) > 0;
+}
std::wostream& operator<<(std::wostream& os, const WideString& str);
std::ostream& operator<<(std::ostream& os, const WideString& str);
diff --git a/core/fxcrt/widestring_unittest.cpp b/core/fxcrt/widestring_unittest.cpp
index 681fb472a2..42819b3349 100644
--- a/core/fxcrt/widestring_unittest.cpp
+++ b/core/fxcrt/widestring_unittest.cpp
@@ -54,29 +54,94 @@ TEST(WideString, OperatorLT) {
WideString a(L"a");
WideString abc(L"\x0110qq"); // Comes before despite endianness.
WideString def(L"\x1001qq"); // Comes after despite endianness.
+ WideStringView v_empty;
+ WideStringView v_a(L"a");
+ WideStringView v_abc(L"\x0110qq");
+ WideStringView v_def(L"\x1001qq");
+ const wchar_t* const c_null = nullptr;
+ const wchar_t* const c_empty = L"";
+ const wchar_t* const c_a = L"a";
+ const wchar_t* const c_abc = L"\x0110qq";
+ const wchar_t* const c_def = L"\x1001qq";
EXPECT_FALSE(empty < empty);
EXPECT_FALSE(a < a);
EXPECT_FALSE(abc < abc);
EXPECT_FALSE(def < def);
+ EXPECT_FALSE(c_null < empty);
+ EXPECT_FALSE(c_empty < empty);
+ EXPECT_FALSE(c_a < a);
+ EXPECT_FALSE(c_abc < abc);
+ EXPECT_FALSE(c_def < def);
+ EXPECT_FALSE(empty < c_null);
+ EXPECT_FALSE(empty < c_empty);
+ EXPECT_FALSE(a < c_a);
+ EXPECT_FALSE(abc < c_abc);
+ EXPECT_FALSE(def < c_def);
+ EXPECT_FALSE(empty < v_empty);
+ EXPECT_FALSE(a < v_a);
+ EXPECT_FALSE(abc < v_abc);
+ EXPECT_FALSE(def < v_def);
EXPECT_TRUE(empty < a);
EXPECT_FALSE(a < empty);
+ EXPECT_TRUE(c_null < a);
+ EXPECT_TRUE(c_empty < a);
+ EXPECT_FALSE(c_a < empty);
+ EXPECT_TRUE(empty < c_a);
+ EXPECT_FALSE(a < c_null);
+ EXPECT_FALSE(a < c_empty);
+ EXPECT_TRUE(empty < v_a);
+ EXPECT_FALSE(a < v_empty);
EXPECT_TRUE(empty < abc);
EXPECT_FALSE(abc < empty);
+ EXPECT_TRUE(c_null < abc);
+ EXPECT_TRUE(c_empty < abc);
+ EXPECT_FALSE(c_abc < empty);
+ EXPECT_TRUE(empty < c_abc);
+ EXPECT_FALSE(abc < c_null);
+ EXPECT_FALSE(abc < c_empty);
+ EXPECT_TRUE(empty < v_abc);
+ EXPECT_FALSE(abc < v_empty);
EXPECT_TRUE(empty < def);
EXPECT_FALSE(def < empty);
+ EXPECT_TRUE(c_null < def);
+ EXPECT_TRUE(c_empty < def);
+ EXPECT_FALSE(c_def < empty);
+ EXPECT_TRUE(empty < c_def);
+ EXPECT_FALSE(def < c_null);
+ EXPECT_FALSE(def < c_empty);
+ EXPECT_TRUE(empty < v_def);
+ EXPECT_FALSE(def < v_empty);
EXPECT_TRUE(a < abc);
EXPECT_FALSE(abc < a);
+ EXPECT_TRUE(c_a < abc);
+ EXPECT_FALSE(c_abc < a);
+ EXPECT_TRUE(a < c_abc);
+ EXPECT_FALSE(abc < c_a);
+ EXPECT_TRUE(a < v_abc);
+ EXPECT_FALSE(abc < v_a);
EXPECT_TRUE(a < def);
EXPECT_FALSE(def < a);
+ EXPECT_TRUE(c_a < def);
+ EXPECT_FALSE(c_def < a);
+ EXPECT_TRUE(a < c_def);
+ EXPECT_FALSE(def < c_a);
+ EXPECT_TRUE(a < v_def);
+ EXPECT_FALSE(def < v_a);
EXPECT_TRUE(abc < def);
EXPECT_FALSE(def < abc);
+ EXPECT_TRUE(c_abc < def);
+ EXPECT_FALSE(c_def < abc);
+ EXPECT_TRUE(abc < c_def);
+ EXPECT_FALSE(def < c_abc);
+ EXPECT_TRUE(abc < v_def);
+ EXPECT_FALSE(def < v_abc);
}
TEST(WideString, OperatorEQ) {
@@ -879,29 +944,59 @@ TEST(WideStringView, OperatorLT) {
WideStringView a(L"a");
WideStringView abc(L"\x0110qq"); // Comes InsertAtFront despite endianness.
WideStringView def(L"\x1001qq"); // Comes InsertAtBack despite endianness.
+ const wchar_t* const c_null = nullptr;
+ const wchar_t* const c_empty = L"";
+ const wchar_t* const c_a = L"a";
+ const wchar_t* const c_abc = L"\x0110qq";
+ const wchar_t* const c_def = L"\x1001qq";
EXPECT_FALSE(empty < empty);
EXPECT_FALSE(a < a);
EXPECT_FALSE(abc < abc);
EXPECT_FALSE(def < def);
+ EXPECT_FALSE(c_null < empty);
+ EXPECT_FALSE(c_empty < empty);
+ EXPECT_FALSE(c_a < a);
+ EXPECT_FALSE(c_abc < abc);
+ EXPECT_FALSE(c_def < def);
+ EXPECT_FALSE(empty < c_null);
+ EXPECT_FALSE(empty < c_empty);
+ EXPECT_FALSE(a < c_a);
+ EXPECT_FALSE(abc < c_abc);
+ EXPECT_FALSE(def < c_def);
EXPECT_TRUE(empty < a);
EXPECT_FALSE(a < empty);
+ EXPECT_TRUE(empty < c_a);
+ EXPECT_FALSE(a < c_null);
+ EXPECT_FALSE(a < c_empty);
EXPECT_TRUE(empty < abc);
EXPECT_FALSE(abc < empty);
+ EXPECT_TRUE(empty < c_abc);
+ EXPECT_FALSE(abc < c_null);
+ EXPECT_FALSE(abc < c_empty);
EXPECT_TRUE(empty < def);
EXPECT_FALSE(def < empty);
+ EXPECT_TRUE(empty < c_def);
+ EXPECT_FALSE(def < c_null);
+ EXPECT_FALSE(def < c_empty);
EXPECT_TRUE(a < abc);
EXPECT_FALSE(abc < a);
+ EXPECT_TRUE(a < c_abc);
+ EXPECT_FALSE(abc < c_a);
EXPECT_TRUE(a < def);
EXPECT_FALSE(def < a);
+ EXPECT_TRUE(a < c_def);
+ EXPECT_FALSE(def < c_a);
EXPECT_TRUE(abc < def);
EXPECT_FALSE(def < abc);
+ EXPECT_TRUE(abc < c_def);
+ EXPECT_FALSE(def < c_abc);
}
TEST(WideStringView, OperatorEQ) {