chore: Nitpicking-utils (#1549)

* nit

* GeneralUtils const-correctness and minor fixes

* use copy instead of reference for char iteration loops

* fix typo and reorganize some functions
This commit is contained in:
jadebenn 2024-04-15 01:14:54 -05:00 committed by GitHub
parent 5049f215ba
commit fafe2aefad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 122 additions and 122 deletions

View File

@ -8,23 +8,23 @@
#include <map>
template <typename T>
inline size_t MinSize(size_t size, const std::basic_string_view<T>& string) {
if (size == size_t(-1) || size > string.size()) {
static inline size_t MinSize(const size_t size, const std::basic_string_view<T> string) {
if (size == SIZE_MAX || size > string.size()) {
return string.size();
} else {
return size;
}
}
inline bool IsLeadSurrogate(char16_t c) {
inline bool IsLeadSurrogate(const char16_t c) {
return (0xD800 <= c) && (c <= 0xDBFF);
}
inline bool IsTrailSurrogate(char16_t c) {
inline bool IsTrailSurrogate(const char16_t c) {
return (0xDC00 <= c) && (c <= 0xDFFF);
}
inline void PushUTF8CodePoint(std::string& ret, char32_t cp) {
inline void PushUTF8CodePoint(std::string& ret, const char32_t cp) {
if (cp <= 0x007F) {
ret.push_back(static_cast<uint8_t>(cp));
} else if (cp <= 0x07FF) {
@ -46,16 +46,16 @@ inline void PushUTF8CodePoint(std::string& ret, char32_t cp) {
constexpr const char16_t REPLACEMENT_CHARACTER = 0xFFFD;
bool _IsSuffixChar(uint8_t c) {
bool static _IsSuffixChar(const uint8_t c) {
return (c & 0xC0) == 0x80;
}
bool GeneralUtils::_NextUTF8Char(std::string_view& slice, uint32_t& out) {
size_t rem = slice.length();
bool GeneralUtils::details::_NextUTF8Char(std::string_view& slice, uint32_t& out) {
const size_t rem = slice.length();
if (slice.empty()) return false;
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&slice.front());
if (rem > 0) {
uint8_t first = bytes[0];
const uint8_t first = bytes[0];
if (first < 0x80) { // 1 byte character
out = static_cast<uint32_t>(first & 0x7F);
slice.remove_prefix(1);
@ -64,7 +64,7 @@ bool GeneralUtils::_NextUTF8Char(std::string_view& slice, uint32_t& out) {
// middle byte, not valid at start, fall through
} else if (first < 0xE0) { // two byte character
if (rem > 1) {
uint8_t second = bytes[1];
const uint8_t second = bytes[1];
if (_IsSuffixChar(second)) {
out = (static_cast<uint32_t>(first & 0x1F) << 6)
+ static_cast<uint32_t>(second & 0x3F);
@ -74,8 +74,8 @@ bool GeneralUtils::_NextUTF8Char(std::string_view& slice, uint32_t& out) {
}
} else if (first < 0xF0) { // three byte character
if (rem > 2) {
uint8_t second = bytes[1];
uint8_t third = bytes[2];
const uint8_t second = bytes[1];
const uint8_t third = bytes[2];
if (_IsSuffixChar(second) && _IsSuffixChar(third)) {
out = (static_cast<uint32_t>(first & 0x0F) << 12)
+ (static_cast<uint32_t>(second & 0x3F) << 6)
@ -86,9 +86,9 @@ bool GeneralUtils::_NextUTF8Char(std::string_view& slice, uint32_t& out) {
}
} else if (first < 0xF8) { // four byte character
if (rem > 3) {
uint8_t second = bytes[1];
uint8_t third = bytes[2];
uint8_t fourth = bytes[3];
const uint8_t second = bytes[1];
const uint8_t third = bytes[2];
const uint8_t fourth = bytes[3];
if (_IsSuffixChar(second) && _IsSuffixChar(third) && _IsSuffixChar(fourth)) {
out = (static_cast<uint32_t>(first & 0x07) << 18)
+ (static_cast<uint32_t>(second & 0x3F) << 12)
@ -107,7 +107,7 @@ bool GeneralUtils::_NextUTF8Char(std::string_view& slice, uint32_t& out) {
}
/// See <https://www.ietf.org/rfc/rfc2781.html#section-2.1>
bool PushUTF16CodePoint(std::u16string& output, uint32_t U, size_t size) {
bool PushUTF16CodePoint(std::u16string& output, const uint32_t U, const size_t size) {
if (output.length() >= size) return false;
if (U < 0x10000) {
// If U < 0x10000, encode U as a 16-bit unsigned integer and terminate.
@ -120,7 +120,7 @@ bool PushUTF16CodePoint(std::u16string& output, uint32_t U, size_t size) {
// Let U' = U - 0x10000. Because U is less than or equal to 0x10FFFF,
// U' must be less than or equal to 0xFFFFF. That is, U' can be
// represented in 20 bits.
uint32_t Ut = U - 0x10000;
const uint32_t Ut = U - 0x10000;
// Initialize two 16-bit unsigned integers, W1 and W2, to 0xD800 and
// 0xDC00, respectively. These integers each have 10 bits free to
@ -141,25 +141,25 @@ bool PushUTF16CodePoint(std::u16string& output, uint32_t U, size_t size) {
} else return false;
}
std::u16string GeneralUtils::UTF8ToUTF16(const std::string_view& string, size_t size) {
size_t newSize = MinSize(size, string);
std::u16string GeneralUtils::UTF8ToUTF16(const std::string_view string, const size_t size) {
const size_t newSize = MinSize(size, string);
std::u16string output;
output.reserve(newSize);
std::string_view iterator = string;
uint32_t c;
while (_NextUTF8Char(iterator, c) && PushUTF16CodePoint(output, c, size)) {}
while (details::_NextUTF8Char(iterator, c) && PushUTF16CodePoint(output, c, size)) {}
return output;
}
//! Converts an std::string (ASCII) to UCS-2 / UTF-16
std::u16string GeneralUtils::ASCIIToUTF16(const std::string_view& string, size_t size) {
size_t newSize = MinSize(size, string);
std::u16string GeneralUtils::ASCIIToUTF16(const std::string_view string, const size_t size) {
const size_t newSize = MinSize(size, string);
std::u16string ret;
ret.reserve(newSize);
for (size_t i = 0; i < newSize; i++) {
char c = string[i];
for (size_t i = 0; i < newSize; ++i) {
const char c = string[i];
// Note: both 7-bit ascii characters and REPLACEMENT_CHARACTER fit in one char16_t
ret.push_back((c > 0 && c <= 127) ? static_cast<char16_t>(c) : REPLACEMENT_CHARACTER);
}
@ -169,18 +169,18 @@ std::u16string GeneralUtils::ASCIIToUTF16(const std::string_view& string, size_t
//! Converts a (potentially-ill-formed) UTF-16 string to UTF-8
//! See: <http://simonsapin.github.io/wtf-8/#decoding-ill-formed-utf-16>
std::string GeneralUtils::UTF16ToWTF8(const std::u16string_view& string, size_t size) {
size_t newSize = MinSize(size, string);
std::string GeneralUtils::UTF16ToWTF8(const std::u16string_view string, const size_t size) {
const size_t newSize = MinSize(size, string);
std::string ret;
ret.reserve(newSize);
for (size_t i = 0; i < newSize; i++) {
char16_t u = string[i];
for (size_t i = 0; i < newSize; ++i) {
const char16_t u = string[i];
if (IsLeadSurrogate(u) && (i + 1) < newSize) {
char16_t next = string[i + 1];
const char16_t next = string[i + 1];
if (IsTrailSurrogate(next)) {
i += 1;
char32_t cp = 0x10000
const char32_t cp = 0x10000
+ ((static_cast<char32_t>(u) - 0xD800) << 10)
+ (static_cast<char32_t>(next) - 0xDC00);
PushUTF8CodePoint(ret, cp);
@ -195,40 +195,40 @@ std::string GeneralUtils::UTF16ToWTF8(const std::u16string_view& string, size_t
return ret;
}
bool GeneralUtils::CaseInsensitiveStringCompare(const std::string& a, const std::string& b) {
bool GeneralUtils::CaseInsensitiveStringCompare(const std::string_view a, const std::string_view b) {
return std::equal(a.begin(), a.end(), b.begin(), b.end(), [](char a, char b) { return tolower(a) == tolower(b); });
}
// MARK: Bits
//! Sets a specific bit in a signed 64-bit integer
int64_t GeneralUtils::SetBit(int64_t value, uint32_t index) {
int64_t GeneralUtils::SetBit(int64_t value, const uint32_t index) {
return value |= 1ULL << index;
}
//! Clears a specific bit in a signed 64-bit integer
int64_t GeneralUtils::ClearBit(int64_t value, uint32_t index) {
int64_t GeneralUtils::ClearBit(int64_t value, const uint32_t index) {
return value &= ~(1ULL << index);
}
//! Checks a specific bit in a signed 64-bit integer
bool GeneralUtils::CheckBit(int64_t value, uint32_t index) {
bool GeneralUtils::CheckBit(int64_t value, const uint32_t index) {
return value & (1ULL << index);
}
bool GeneralUtils::ReplaceInString(std::string& str, const std::string& from, const std::string& to) {
size_t start_pos = str.find(from);
bool GeneralUtils::ReplaceInString(std::string& str, const std::string_view from, const std::string_view to) {
const size_t start_pos = str.find(from);
if (start_pos == std::string::npos)
return false;
str.replace(start_pos, from.length(), to);
return true;
}
std::vector<std::wstring> GeneralUtils::SplitString(std::wstring& str, wchar_t delimiter) {
std::vector<std::wstring> GeneralUtils::SplitString(const std::wstring_view str, const wchar_t delimiter) {
std::vector<std::wstring> vector = std::vector<std::wstring>();
std::wstring current;
for (const auto& c : str) {
for (const wchar_t c : str) {
if (c == delimiter) {
vector.push_back(current);
current = L"";
@ -237,15 +237,15 @@ std::vector<std::wstring> GeneralUtils::SplitString(std::wstring& str, wchar_t d
}
}
vector.push_back(current);
vector.push_back(std::move(current));
return vector;
}
std::vector<std::u16string> GeneralUtils::SplitString(const std::u16string& str, char16_t delimiter) {
std::vector<std::u16string> GeneralUtils::SplitString(const std::u16string_view str, const char16_t delimiter) {
std::vector<std::u16string> vector = std::vector<std::u16string>();
std::u16string current;
for (const auto& c : str) {
for (const char16_t c : str) {
if (c == delimiter) {
vector.push_back(current);
current = u"";
@ -254,17 +254,15 @@ std::vector<std::u16string> GeneralUtils::SplitString(const std::u16string& str,
}
}
vector.push_back(current);
vector.push_back(std::move(current));
return vector;
}
std::vector<std::string> GeneralUtils::SplitString(const std::string& str, char delimiter) {
std::vector<std::string> GeneralUtils::SplitString(const std::string_view str, const char delimiter) {
std::vector<std::string> vector = std::vector<std::string>();
std::string current = "";
for (size_t i = 0; i < str.length(); i++) {
char c = str[i];
for (const char c : str) {
if (c == delimiter) {
vector.push_back(current);
current = "";
@ -273,8 +271,7 @@ std::vector<std::string> GeneralUtils::SplitString(const std::string& str, char
}
}
vector.push_back(current);
vector.push_back(std::move(current));
return vector;
}
@ -283,7 +280,7 @@ std::u16string GeneralUtils::ReadWString(RakNet::BitStream& inStream) {
inStream.Read<uint32_t>(length);
std::u16string string;
for (auto i = 0; i < length; i++) {
for (uint32_t i = 0; i < length; ++i) {
uint16_t c;
inStream.Read(c);
string.push_back(c);
@ -292,29 +289,29 @@ std::u16string GeneralUtils::ReadWString(RakNet::BitStream& inStream) {
return string;
}
std::vector<std::string> GeneralUtils::GetSqlFileNamesFromFolder(const std::string& folder) {
std::vector<std::string> GeneralUtils::GetSqlFileNamesFromFolder(const std::string_view folder) {
// Because we dont know how large the initial number before the first _ is we need to make it a map like so.
std::map<uint32_t, std::string> filenames{};
for (auto& t : std::filesystem::directory_iterator(folder)) {
auto filename = t.path().filename().string();
auto index = std::stoi(GeneralUtils::SplitString(filename, '_').at(0));
filenames.insert(std::make_pair(index, filename));
std::map<uint32_t, std::string> filenames{};
for (const auto& t : std::filesystem::directory_iterator(folder)) {
auto filename = t.path().filename().string();
const auto index = std::stoi(GeneralUtils::SplitString(filename, '_').at(0));
filenames.emplace(index, std::move(filename));
}
// Now sort the map by the oldest migration.
std::vector<std::string> sortedFiles{};
auto fileIterator = filenames.begin();
std::map<uint32_t, std::string>::iterator oldest = filenames.begin();
auto fileIterator = filenames.cbegin();
auto oldest = filenames.cbegin();
while (!filenames.empty()) {
if (fileIterator == filenames.end()) {
if (fileIterator == filenames.cend()) {
sortedFiles.push_back(oldest->second);
filenames.erase(oldest);
fileIterator = filenames.begin();
oldest = filenames.begin();
fileIterator = filenames.cbegin();
oldest = filenames.cbegin();
continue;
}
if (oldest->first > fileIterator->first) oldest = fileIterator;
fileIterator++;
++fileIterator;
}
return sortedFiles;

View File

@ -3,17 +3,18 @@
// C++
#include <charconv>
#include <cstdint>
#include <random>
#include <ctime>
#include <functional>
#include <optional>
#include <random>
#include <span>
#include <stdexcept>
#include <string>
#include <string_view>
#include <optional>
#include <functional>
#include <type_traits>
#include <stdexcept>
#include "BitStream.h"
#include "NiPoint3.h"
#include "dPlatforms.h"
#include "Game.h"
#include "Logger.h"
@ -32,29 +33,31 @@ namespace GeneralUtils {
//! Converts a plain ASCII string to a UTF-16 string
/*!
\param string The string to convert
\param size A size to trim the string to. Default is -1 (No trimming)
\param size A size to trim the string to. Default is SIZE_MAX (No trimming)
\return An UTF-16 representation of the string
*/
std::u16string ASCIIToUTF16(const std::string_view& string, size_t size = -1);
std::u16string ASCIIToUTF16(const std::string_view string, const size_t size = SIZE_MAX);
//! Converts a UTF-8 String to a UTF-16 string
/*!
\param string The string to convert
\param size A size to trim the string to. Default is -1 (No trimming)
\param size A size to trim the string to. Default is SIZE_MAX (No trimming)
\return An UTF-16 representation of the string
*/
std::u16string UTF8ToUTF16(const std::string_view& string, size_t size = -1);
std::u16string UTF8ToUTF16(const std::string_view string, const size_t size = SIZE_MAX);
//! Internal, do not use
bool _NextUTF8Char(std::string_view& slice, uint32_t& out);
namespace details {
//! Internal, do not use
bool _NextUTF8Char(std::string_view& slice, uint32_t& out);
}
//! Converts a UTF-16 string to a UTF-8 string
/*!
\param string The string to convert
\param size A size to trim the string to. Default is -1 (No trimming)
\param size A size to trim the string to. Default is SIZE_MAX (No trimming)
\return An UTF-8 representation of the string
*/
std::string UTF16ToWTF8(const std::u16string_view& string, size_t size = -1);
std::string UTF16ToWTF8(const std::u16string_view string, const size_t size = SIZE_MAX);
/**
* Compares two basic strings but does so ignoring case sensitivity
@ -62,7 +65,7 @@ namespace GeneralUtils {
* \param b the second string to compare against the first string
* @return if the two strings are equal
*/
bool CaseInsensitiveStringCompare(const std::string& a, const std::string& b);
bool CaseInsensitiveStringCompare(const std::string_view a, const std::string_view b);
// MARK: Bits
@ -70,9 +73,9 @@ namespace GeneralUtils {
//! Sets a bit on a numerical value
template <typename T>
inline void SetBit(T& value, eObjectBits bits) {
inline void SetBit(T& value, const eObjectBits bits) {
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
auto index = static_cast<size_t>(bits);
const auto index = static_cast<size_t>(bits);
if (index > (sizeof(T) * 8) - 1) {
return;
}
@ -82,9 +85,9 @@ namespace GeneralUtils {
//! Clears a bit on a numerical value
template <typename T>
inline void ClearBit(T& value, eObjectBits bits) {
inline void ClearBit(T& value, const eObjectBits bits) {
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
auto index = static_cast<size_t>(bits);
const auto index = static_cast<size_t>(bits);
if (index > (sizeof(T) * 8 - 1)) {
return;
}
@ -97,14 +100,14 @@ namespace GeneralUtils {
\param value The value to set the bit for
\param index The index of the bit
*/
int64_t SetBit(int64_t value, uint32_t index);
int64_t SetBit(int64_t value, const uint32_t index);
//! Clears a specific bit in a signed 64-bit integer
/*!
\param value The value to clear the bit from
\param index The index of the bit
*/
int64_t ClearBit(int64_t value, uint32_t index);
int64_t ClearBit(int64_t value, const uint32_t index);
//! Checks a specific bit in a signed 64-bit integer
/*!
@ -112,19 +115,19 @@ namespace GeneralUtils {
\param index The index of the bit
\return Whether or not the bit is set
*/
bool CheckBit(int64_t value, uint32_t index);
bool CheckBit(int64_t value, const uint32_t index);
bool ReplaceInString(std::string& str, const std::string& from, const std::string& to);
bool ReplaceInString(std::string& str, const std::string_view from, const std::string_view to);
std::u16string ReadWString(RakNet::BitStream& inStream);
std::vector<std::wstring> SplitString(std::wstring& str, wchar_t delimiter);
std::vector<std::wstring> SplitString(const std::wstring_view str, const wchar_t delimiter);
std::vector<std::u16string> SplitString(const std::u16string& str, char16_t delimiter);
std::vector<std::u16string> SplitString(const std::u16string_view str, const char16_t delimiter);
std::vector<std::string> SplitString(const std::string& str, char delimiter);
std::vector<std::string> SplitString(const std::string_view str, const char delimiter);
std::vector<std::string> GetSqlFileNamesFromFolder(const std::string& folder);
std::vector<std::string> GetSqlFileNamesFromFolder(const std::string_view folder);
// Concept constraining to enum types
template <typename T>
@ -144,7 +147,7 @@ namespace GeneralUtils {
// If a boolean, present an alias to an intermediate integral type for parsing
template <Numeric T> requires std::same_as<T, bool>
struct numeric_parse<T> { using type = uint32_t; };
struct numeric_parse<T> { using type = uint8_t; };
// Shorthand type alias
template <Numeric T>
@ -205,7 +208,7 @@ namespace GeneralUtils {
* @returns An std::optional containing the desired NiPoint3 if it can be constructed from the string parameters
*/
template <typename T>
[[nodiscard]] std::optional<NiPoint3> TryParse(const std::string& strX, const std::string& strY, const std::string& strZ) {
[[nodiscard]] std::optional<NiPoint3> TryParse(const std::string_view strX, const std::string_view strY, const std::string_view strZ) {
const auto x = TryParse<float>(strX);
if (!x) return std::nullopt;
@ -217,17 +220,17 @@ namespace GeneralUtils {
}
/**
* The TryParse overload for handling NiPoint3 by passingn a reference to a vector of three strings
* @param str The string vector representing the X, Y, and Xcoordinates
* The TryParse overload for handling NiPoint3 by passing a span of three strings
* @param str The string vector representing the X, Y, and Z coordinates
* @returns An std::optional containing the desired NiPoint3 if it can be constructed from the string parameters
*/
template <typename T>
[[nodiscard]] std::optional<NiPoint3> TryParse(const std::vector<std::string>& str) {
[[nodiscard]] std::optional<NiPoint3> TryParse(const std::span<const std::string> str) {
return (str.size() == 3) ? TryParse<NiPoint3>(str[0], str[1], str[2]) : std::nullopt;
}
template <typename T>
std::u16string to_u16string(T value) {
std::u16string to_u16string(const T value) {
return GeneralUtils::ASCIIToUTF16(std::to_string(value));
}
@ -246,7 +249,7 @@ namespace GeneralUtils {
\param max The maximum to generate to
*/
template <typename T>
inline T GenerateRandomNumber(std::size_t min, std::size_t max) {
inline T GenerateRandomNumber(const std::size_t min, const std::size_t max) {
// Make sure it is a numeric type
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
@ -273,10 +276,10 @@ namespace GeneralUtils {
// on Windows we need to undef these or else they conflict with our numeric limits calls
// DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS
#ifdef _WIN32
#undef min
#undef max
#endif
#ifdef _WIN32
#undef min
#undef max
#endif
template <typename T>
inline T GenerateRandomNumber() {

View File

@ -15,12 +15,12 @@ TEST_F(EncodingTest, TestEncodingHello) {
originalWord = "Hello World!";
originalWordSv = originalWord;
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 'H');
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 'e');
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 'l');
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 'l');
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 'o');
EXPECT_EQ(GeneralUtils::_NextUTF8Char(originalWordSv, out), true);
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 'H');
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 'e');
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 'l');
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 'l');
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 'o');
EXPECT_EQ(GeneralUtils::details::_NextUTF8Char(originalWordSv, out), true);
EXPECT_EQ(GeneralUtils::UTF8ToUTF16("Hello World!"), u"Hello World!");
};
@ -29,15 +29,15 @@ TEST_F(EncodingTest, TestEncodingUmlaut) {
originalWord = reinterpret_cast<const char*>(u8"Frühling");
originalWordSv = originalWord;
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'F');
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'r');
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'ü');
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'h');
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'l');
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'i');
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'n');
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'g');
EXPECT_EQ(GeneralUtils::_NextUTF8Char(originalWordSv, out), false);
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'F');
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'r');
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'ü');
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'h');
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'l');
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'i');
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'n');
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'g');
EXPECT_EQ(GeneralUtils::details::_NextUTF8Char(originalWordSv, out), false);
EXPECT_EQ(GeneralUtils::UTF8ToUTF16("Frühling"), u"Frühling");
};
@ -46,10 +46,10 @@ TEST_F(EncodingTest, TestEncodingChinese) {
originalWord = "中文字";
originalWordSv = originalWord;
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'');
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'');
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'');
EXPECT_EQ(GeneralUtils::_NextUTF8Char(originalWordSv, out), false);
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'');
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'');
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, U'');
EXPECT_EQ(GeneralUtils::details::_NextUTF8Char(originalWordSv, out), false);
EXPECT_EQ(GeneralUtils::UTF8ToUTF16("中文字"), u"中文字");
};
@ -58,11 +58,11 @@ TEST_F(EncodingTest, TestEncodingEmoji) {
originalWord = "👨‍⚖️";
originalWordSv = originalWord;
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 0x1F468);
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 0x200D);
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 0x2696);
GeneralUtils::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 0xFE0F);
EXPECT_EQ(GeneralUtils::_NextUTF8Char(originalWordSv, out), false);
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 0x1F468);
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 0x200D);
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 0x2696);
GeneralUtils::details::_NextUTF8Char(originalWordSv, out); EXPECT_EQ(out, 0xFE0F);
EXPECT_EQ(GeneralUtils::details::_NextUTF8Char(originalWordSv, out), false);
EXPECT_EQ(GeneralUtils::UTF8ToUTF16("👨‍⚖️"), u"👨‍⚖️");
};