string: add variants for char16_t/char16_t strncmp
Some checks failed
Doxygen Action / build (push) Has been cancelled
Some checks failed
Doxygen Action / build (push) Has been cancelled
Technically, this is still binary compare with no locale-specific ordering knowledge. But takes Unicode representation of UTF-16 surrogate pairs when comparing. Signed-off-by: Simon Rozman <simon.rozman@amebis.si>
This commit is contained in:
@@ -1066,6 +1066,103 @@ namespace stdex
|
||||
reinterpret_cast<const utf16_t*>(str2), N2);
|
||||
}
|
||||
|
||||
///
|
||||
/// Binary compare two strings
|
||||
///
|
||||
/// \param[in] str1 String 1
|
||||
/// \param[in] count1 String 1 code unit count limit
|
||||
/// \param[in] str2 String 2
|
||||
/// \param[in] count2 String 2 code unit count limit
|
||||
///
|
||||
/// \return Negative if str1<str2; positive if str1>str2; zero if str1==str2
|
||||
///
|
||||
inline int strncmp(
|
||||
_In_reads_or_z_opt_(count1) const utf16_t* str1, _In_ size_t count1,
|
||||
_In_reads_or_z_opt_(count2) const utf16_t* str2, _In_ size_t count2)
|
||||
{
|
||||
stdex_assert(str1 || !count1);
|
||||
stdex_assert(str2 || !count2);
|
||||
for (size_t i = 0, j = 0; ;) {
|
||||
if (i >= count1 && j >= count2) return 0;
|
||||
if (i >= count1 && j < count2) return -1;
|
||||
if (i < count1 && j >= count2) return +1;
|
||||
|
||||
utf32_t a;
|
||||
if (i + 1 >= count1 || !is_surrogate_pair(&str1[i])) {
|
||||
a = static_cast<utf16_t>(str1[i]);
|
||||
i++;
|
||||
}
|
||||
else {
|
||||
a = surrogate_pair_to_ucs4(&str1[i]);
|
||||
i += 2;
|
||||
}
|
||||
utf32_t b;
|
||||
if (j + 1 >= count2 || !is_surrogate_pair(&str2[j])) {
|
||||
b = static_cast<utf16_t>(str2[j]);
|
||||
j++;
|
||||
}
|
||||
else {
|
||||
b = surrogate_pair_to_ucs4(&str2[j]);
|
||||
j += 2;
|
||||
}
|
||||
if (a < b) return -1;
|
||||
if (a > b) return +1;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Binary compare two strings
|
||||
///
|
||||
/// \param[in] str1 String 1
|
||||
/// \param[in] count1 String 1 code unit count limit
|
||||
/// \param[in] str2 String 2
|
||||
/// \param[in] count2 String 2 code unit count limit
|
||||
///
|
||||
/// \return Negative if str1<str2; positive if str1>str2; zero if str1==str2
|
||||
///
|
||||
inline int strncmp(
|
||||
_In_reads_or_z_opt_(count1) const char16_t* str1, _In_ size_t count1,
|
||||
_In_reads_or_z_opt_(count2) const char16_t* str2, _In_ size_t count2)
|
||||
{
|
||||
return strncmp(
|
||||
reinterpret_cast<const utf16_t*>(str1), count1,
|
||||
reinterpret_cast<const utf16_t*>(str2), count2);
|
||||
}
|
||||
|
||||
///
|
||||
/// Binary compare two strings
|
||||
///
|
||||
/// \param[in] str1 String 1
|
||||
/// \param[in] str2 String 2
|
||||
///
|
||||
/// \return Negative if str1<str2; positive if str1>str2; zero if str1==str2
|
||||
///
|
||||
template <size_t N1, size_t N2>
|
||||
int strncmp(
|
||||
_In_ const utf16_t(&str1)[N1],
|
||||
_In_ const utf16_t(&str2)[N2])
|
||||
{
|
||||
return strncmp(str1, N1, str2, N2);
|
||||
}
|
||||
|
||||
///
|
||||
/// Binary compare two strings
|
||||
///
|
||||
/// \param[in] str1 String 1
|
||||
/// \param[in] str2 String 2
|
||||
///
|
||||
/// \return Negative if str1<str2; positive if str1>str2; zero if str1==str2
|
||||
///
|
||||
template <size_t N1, size_t N2>
|
||||
int strncmp(
|
||||
_In_ const char16_t(&str1)[N1],
|
||||
_In_ const char16_t(&str2)[N2])
|
||||
{
|
||||
return strncmp(
|
||||
reinterpret_cast<const utf16_t*>(str1), N1,
|
||||
reinterpret_cast<const utf16_t*>(str2), N2);
|
||||
}
|
||||
|
||||
///
|
||||
/// Binary compare two strings in reverse direction
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user