diff options
author | Treeston <treeston.mmoc@gmail.com> | 2020-08-23 00:31:57 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2022-02-04 00:27:12 +0100 |
commit | 0473beff2bef388373dabc756b829f48bb9d1a4e (patch) | |
tree | 9432dbbe9c0da4d5e15f999fdf61e47e40b10f91 /src | |
parent | 5ba95cb42f9354e5be923629c32be71cf2705324 (diff) |
Core/Misc: std::string -> std::string_view in a bunch of places, notably chat commands and Util.h
(cherry picked from commit a41bbd9ad9adedb15c7133bdef1575a6ec0eb1ab)
Diffstat (limited to 'src')
-rw-r--r-- | src/common/Utilities/Util.cpp | 54 | ||||
-rw-r--r-- | src/common/Utilities/Util.h | 78 | ||||
-rw-r--r-- | src/server/game/Chat/ChatCommands/ChatCommandArgs.h | 76 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_go.cpp | 8 |
4 files changed, 104 insertions, 112 deletions
diff --git a/src/common/Utilities/Util.cpp b/src/common/Utilities/Util.cpp index 42064cc3466..914aed5816c 100644 --- a/src/common/Utilities/Util.cpp +++ b/src/common/Utilities/Util.cpp @@ -35,10 +35,10 @@ #include <arpa/inet.h> #endif -Tokenizer::Tokenizer(const std::string &src, const char sep, uint32 vectorReserve /*= 0*/, bool keepEmptyStrings /*= true*/) +Tokenizer::Tokenizer(std::string_view src, const char sep, uint32 vectorReserve /*= 0*/, bool keepEmptyStrings /*= true*/) { m_str = new char[src.length() + 1]; - memcpy(m_str, src.c_str(), src.length() + 1); + memcpy(m_str, src.data(), src.length() + 1); if (vectorReserve) m_storage.reserve(vectorReserve); @@ -400,12 +400,12 @@ bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize) return true; } -bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr) +bool Utf8toWStr(std::string_view utf8str, std::wstring& wstr) { wstr.clear(); try { - utf8::utf8to16(utf8str.c_str(), utf8str.c_str()+utf8str.size(), std::back_inserter(wstr)); + utf8::utf8to16(utf8str.begin(), utf8str.end(), std::back_inserter(wstr)); } catch (std::exception const&) { @@ -439,7 +439,7 @@ bool WStrToUtf8(wchar_t const* wstr, size_t size, std::string& utf8str) return true; } -bool WStrToUtf8(std::wstring const& wstr, std::string& utf8str) +bool WStrToUtf8(std::wstring_view wstr, std::string& utf8str) { try { @@ -448,7 +448,7 @@ bool WStrToUtf8(std::wstring const& wstr, std::string& utf8str) if (wstr.size()) { - char* oend = utf8::utf16to8(wstr.c_str(), wstr.c_str()+wstr.size(), &utf8str2[0]); + char* oend = utf8::utf16to8(wstr.begin(), wstr.end(), &utf8str2[0]); utf8str2.resize(oend-(&utf8str2[0])); // remove unused tail } utf8str = utf8str2; @@ -462,7 +462,12 @@ bool WStrToUtf8(std::wstring const& wstr, std::string& utf8str) return true; } -std::wstring wstrCaseAccentInsensitiveParse(std::wstring const& wstr, LocaleConstant locale) +void wstrToUpper(std::wstring& str) { std::transform(std::begin(str), std::end(str), std::begin(str), wcharToUpper); } +void wstrToLower(std::wstring& str) { std::transform(std::begin(str), std::end(str), std::begin(str), wcharToLower); } +void strToUpper(std::string& str) { std::transform(std::begin(str), std::end(str), std::begin(str), charToUpper); } +void strToLower(std::string& str) { std::transform(std::begin(str), std::end(str), std::begin(str), charToLower); } + +std::wstring wstrCaseAccentInsensitiveParse(std::wstring_view wstr, LocaleConstant locale) { std::wstring result; result.reserve(wstr.length() * 2); @@ -647,21 +652,6 @@ std::wstring wstrCaseAccentInsensitiveParse(std::wstring const& wstr, LocaleCons return result; } -void wstrToUpper(std::wstring& str) -{ - std::transform(str.begin(), str.end(), str.begin(), wcharToUpper); -} - -void strToLower(std::string& str) -{ - std::transform(str.begin(), str.end(), str.begin(), [](char c) { return std::tolower(c); }); -} - -void wstrToLower(std::wstring& str) -{ - std::transform(str.begin(), str.end(), str.begin(), wcharToLower); -} - std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension) { // supported only Cyrillic cases @@ -711,7 +701,7 @@ std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension) return wname; } -bool utf8ToConsole(const std::string& utf8str, std::string& conStr) +bool utf8ToConsole(std::string_view utf8str, std::string& conStr) { #if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS std::wstring wstr; @@ -728,7 +718,7 @@ bool utf8ToConsole(const std::string& utf8str, std::string& conStr) return true; } -bool consoleToUtf8(const std::string& conStr, std::string& utf8str) +bool consoleToUtf8(std::string_view conStr, std::string& utf8str) { #if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS std::wstring wstr; @@ -743,7 +733,7 @@ bool consoleToUtf8(const std::string& conStr, std::string& utf8str) #endif } -bool Utf8FitTo(const std::string& str, std::wstring const& search) +bool Utf8FitTo(std::string_view str, std::wstring_view search) { std::wstring temp; @@ -823,7 +813,7 @@ std::string Trinity::Impl::ByteArrayToHexStr(uint8 const* bytes, size_t arrayLen return ss.str(); } -void Trinity::Impl::HexStrToByteArray(std::string const& str, uint8* out, size_t outlen, bool reverse /*= false*/) +void Trinity::Impl::HexStrToByteArray(std::string_view str, uint8* out, size_t outlen, bool reverse /*= false*/) { ASSERT(str.size() == (2 * outlen)); @@ -846,14 +836,12 @@ void Trinity::Impl::HexStrToByteArray(std::string const& str, uint8* out, size_t } } -bool StringToBool(std::string const& str) +bool StringToBool(std::string_view str) { - std::string lowerStr = str; - std::transform(str.begin(), str.end(), lowerStr.begin(), [](char c) { return char(::tolower(c)); }); - return lowerStr == "1" || lowerStr == "true" || lowerStr == "yes"; + return ((str == "1") || StringEqualI(str, "true") || StringEqualI(str, "yes")); } -bool StringEqualI(std::string const& str1, std::string const& str2) +bool StringEqualI(std::string_view str1, std::string_view str2) { return std::equal(str1.begin(), str1.end(), str2.begin(), str2.end(), [](char a, char b) @@ -862,12 +850,12 @@ bool StringEqualI(std::string const& str1, std::string const& str2) }); } -bool StringStartsWith(std::string const& haystack, std::string const& needle) +bool StringStartsWith(std::string_view haystack, std::string_view needle) { return (haystack.rfind(needle, 0) == 0); } -bool StringContainsStringI(std::string const& haystack, std::string const& needle) +bool StringContainsStringI(std::string_view haystack, std::string_view needle) { return haystack.end() != std::search(haystack.begin(), haystack.end(), needle.begin(), needle.end(), [](char c1, char c2) { return std::toupper(c1) == std::toupper(c2); }); diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h index d048f3437aa..95c1fd0ee00 100644 --- a/src/common/Utilities/Util.h +++ b/src/common/Utilities/Util.h @@ -22,6 +22,7 @@ #include "Errors.h" #include <array> #include <string> +#include <string_view> #include <utility> #include <vector> @@ -46,7 +47,7 @@ public: typedef StorageType::const_reference const_reference; public: - Tokenizer(const std::string &src, char const sep, uint32 vectorReserve = 0, bool keepEmptyStrings = true); + Tokenizer(std::string_view src, char const sep, uint32 vectorReserve = 0, bool keepEmptyStrings = true); ~Tokenizer() { delete[] m_str; } const_iterator begin() const { return m_storage.begin(); } @@ -110,17 +111,17 @@ template <class T> inline T square(T x) { return x*x; } // UTF8 handling -TC_COMMON_API bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr); +TC_COMMON_API bool Utf8toWStr(std::string_view utf8str, std::wstring& wstr); // in wsize==max size of buffer, out wsize==real string size TC_COMMON_API bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize); -inline bool Utf8toWStr(const std::string& utf8str, wchar_t* wstr, size_t& wsize) +inline bool Utf8toWStr(std::string_view utf8str, wchar_t* wstr, size_t& wsize) { - return Utf8toWStr(utf8str.c_str(), utf8str.size(), wstr, wsize); + return Utf8toWStr(utf8str.data(), utf8str.size(), wstr, wsize); } -TC_COMMON_API bool WStrToUtf8(std::wstring const& wstr, std::string& utf8str); +TC_COMMON_API bool WStrToUtf8(std::wstring_view wstr, std::string& utf8str); // size==real string size TC_COMMON_API bool WStrToUtf8(wchar_t const* wstr, size_t size, std::string& utf8str); @@ -212,34 +213,34 @@ inline bool isNumericOrSpace(wchar_t wchar) return isNumeric(wchar) || wchar == L' '; } -inline bool isBasicLatinString(const std::wstring &wstr, bool numericOrSpace) +inline bool isBasicLatinString(std::wstring_view wstr, bool numericOrSpace) { - for (size_t i = 0; i < wstr.size(); ++i) - if (!isBasicLatinCharacter(wstr[i]) && (!numericOrSpace || !isNumericOrSpace(wstr[i]))) + for (wchar_t c : wstr) + if (!isBasicLatinCharacter(c) && (!numericOrSpace || !isNumericOrSpace(c))) return false; return true; } -inline bool isExtendedLatinString(const std::wstring &wstr, bool numericOrSpace) +inline bool isExtendedLatinString(std::wstring_view wstr, bool numericOrSpace) { - for (size_t i = 0; i < wstr.size(); ++i) - if (!isExtendedLatinCharacter(wstr[i]) && (!numericOrSpace || !isNumericOrSpace(wstr[i]))) + for (wchar_t c : wstr) + if (!isExtendedLatinCharacter(c) && (!numericOrSpace || !isNumericOrSpace(c))) return false; return true; } -inline bool isCyrillicString(const std::wstring &wstr, bool numericOrSpace) +inline bool isCyrillicString(std::wstring_view wstr, bool numericOrSpace) { - for (size_t i = 0; i < wstr.size(); ++i) - if (!isCyrillicCharacter(wstr[i]) && (!numericOrSpace || !isNumericOrSpace(wstr[i]))) + for (wchar_t c : wstr) + if (!isCyrillicCharacter(c) && (!numericOrSpace || !isNumericOrSpace(c))) return false; return true; } -inline bool isEastAsianString(const std::wstring &wstr, bool numericOrSpace) +inline bool isEastAsianString(std::wstring_view wstr, bool numericOrSpace) { - for (size_t i = 0; i < wstr.size(); ++i) - if (!isEastAsianCharacter(wstr[i]) && (!numericOrSpace || !isNumericOrSpace(wstr[i]))) + for (wchar_t c : wstr) + if (!isEastAsianCharacter(c) && (!numericOrSpace || !isNumericOrSpace(c))) return false; return true; } @@ -321,17 +322,21 @@ inline bool isUpper(wchar_t wchar) return !isLower(wchar); } -TC_COMMON_API std::wstring wstrCaseAccentInsensitiveParse(std::wstring const& wstr, LocaleConstant locale); +inline char charToUpper(char c) { return std::toupper(c); } +inline char charToLower(char c) { return std::tolower(c); } TC_COMMON_API void wstrToUpper(std::wstring& str); -TC_COMMON_API void strToLower(std::string& str); TC_COMMON_API void wstrToLower(std::wstring& str); +TC_COMMON_API void strToUpper(std::string& str); +TC_COMMON_API void strToLower(std::string& str); + +TC_COMMON_API std::wstring wstrCaseAccentInsensitiveParse(std::wstring_view wstr, LocaleConstant locale); TC_COMMON_API std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension); -TC_COMMON_API bool utf8ToConsole(const std::string& utf8str, std::string& conStr); -TC_COMMON_API bool consoleToUtf8(const std::string& conStr, std::string& utf8str); -TC_COMMON_API bool Utf8FitTo(const std::string& str, std::wstring const& search); +TC_COMMON_API bool utf8ToConsole(std::string_view utf8str, std::string& conStr); +TC_COMMON_API bool consoleToUtf8(std::string_view conStr, std::string& utf8str); +TC_COMMON_API bool Utf8FitTo(std::string_view str, std::wstring_view search); TC_COMMON_API void utf8printf(FILE* out, const char *str, ...); TC_COMMON_API void vutf8printf(FILE* out, const char *str, va_list* ap); TC_COMMON_API bool Utf8ToUpperOnlyLatin(std::string& utf8String); @@ -344,7 +349,7 @@ TC_COMMON_API uint32 GetPID(); namespace Trinity::Impl { TC_COMMON_API std::string ByteArrayToHexStr(uint8 const* bytes, size_t length, bool reverse = false); - TC_COMMON_API void HexStrToByteArray(std::string const& str, uint8* out, size_t outlen, bool reverse = false); + TC_COMMON_API void HexStrToByteArray(std::string_view str, uint8* out, size_t outlen, bool reverse = false); } template <typename Container> @@ -354,19 +359,19 @@ std::string ByteArrayToHexStr(Container const& c, bool reverse = false) } template <size_t Size> -void HexStrToByteArray(std::string const& str, std::array<uint8, Size>& buf, bool reverse = false) +void HexStrToByteArray(std::string_view str, std::array<uint8, Size>& buf, bool reverse = false) { Trinity::Impl::HexStrToByteArray(str, buf.data(), Size, reverse); } template <size_t Size> -std::array<uint8, Size> HexStrToByteArray(std::string const& str, bool reverse = false) +std::array<uint8, Size> HexStrToByteArray(std::string_view str, bool reverse = false) { std::array<uint8, Size> arr; HexStrToByteArray(str, arr, reverse); return arr; } -inline std::vector<uint8> HexStrToByteVector(std::string const& str, bool reverse = false) +inline std::vector<uint8> HexStrToByteVector(std::string_view str, bool reverse = false) { std::vector<uint8> buf; size_t const sz = (str.size() / 2); @@ -375,14 +380,14 @@ inline std::vector<uint8> HexStrToByteVector(std::string const& str, bool revers return buf; } -TC_COMMON_API bool StringToBool(std::string const& str); +TC_COMMON_API bool StringToBool(std::string_view str); TC_COMMON_API float DegToRad(float degrees); -TC_COMMON_API bool StringEqualI(std::string const& str1, std::string const& str2); -TC_COMMON_API bool StringStartsWith(std::string const& haystack, std::string const& needle); -TC_COMMON_API bool StringContainsStringI(std::string const& haystack, std::string const& needle); +TC_COMMON_API bool StringEqualI(std::string_view str1, std::string_view str2); +TC_COMMON_API bool StringStartsWith(std::string_view haystack, std::string_view needle); +TC_COMMON_API bool StringContainsStringI(std::string_view haystack, std::string_view needle); template <typename T> -inline bool ValueContainsStringI(std::pair<T, std::string> const& haystack, std::string const& needle) +inline bool ValueContainsStringI(std::pair<T, std::string_view> const& haystack, std::string_view needle) { return StringContainsStringI(haystack.second, needle); } @@ -599,16 +604,13 @@ constexpr typename std::underlying_type<E>::type AsUnderlyingType(E enumValue) return static_cast<typename std::underlying_type<E>::type>(enumValue); } -template<typename Ret, typename Only> -Ret* Coalesce(Only* arg) -{ - return arg; -} - template<typename Ret, typename T1, typename... T> Ret* Coalesce(T1* first, T*... rest) { - return static_cast<Ret*>(first ? static_cast<Ret*>(first) : Coalesce<Ret>(rest...)); + if constexpr (sizeof...(T) > 0) + return (first ? static_cast<Ret*>(first) : Coalesce<Ret>(rest...)); + else + return static_cast<Ret*>(first); } template<typename T> diff --git a/src/server/game/Chat/ChatCommands/ChatCommandArgs.h b/src/server/game/Chat/ChatCommands/ChatCommandArgs.h index a90790265ca..8a723686196 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommandArgs.h +++ b/src/server/game/Chat/ChatCommands/ChatCommandArgs.h @@ -22,7 +22,10 @@ #include "ChatCommandTags.h" #include "SmartEnum.h" #include "Util.h" +#include <charconv> #include <map> +#include <string> +#include <string_view> struct GameTele; @@ -43,42 +46,26 @@ namespace ChatCommands template <typename T, typename = void> struct ArgInfo { static_assert(!std::is_same_v<T,T>, "Invalid command parameter type - see ChatCommandArgs.h for possible types"); }; -// catch-all for signed integral types +// catch-all for integral types template <typename T> -struct ArgInfo<T, std::enable_if_t<std::is_integral_v<T> && std::is_signed_v<T>>> +struct ArgInfo<T, std::enable_if_t<std::is_integral_v<T>>> { static char const* TryConsume(T& val, char const* args) { char const* next = args; - std::string token(args, Trinity::Impl::ChatCommands::tokenize(next)); - try - { - size_t processedChars = 0; - val = std::stoll(token, &processedChars, 0); - if (processedChars != token.length()) - return nullptr; - } - catch (...) { return nullptr; } - return next; - } -}; + std::string_view token(args, Trinity::Impl::ChatCommands::tokenize(next)); + + std::from_chars_result result; + if (StringStartsWith(token, "0x")) + result = std::from_chars(token.data() + 2, token.data() + token.length(), val, 16); + else if (StringStartsWith(token, "0b")) + result = std::from_chars(token.data() + 2, token.data() + token.length(), val, 2); + else + result = std::from_chars(token.data(), token.data() + token.length(), val, 10); + + if ((token.data() + token.length()) != result.ptr) + return nullptr; -// catch-all for unsigned integral types -template <typename T> -struct ArgInfo<T, std::enable_if_t<std::is_integral_v<T> && std::is_unsigned_v<T>>> -{ - static char const* TryConsume(T& val, char const* args) - { - char const* next = args; - std::string token(args, Trinity::Impl::ChatCommands::tokenize(next)); - try - { - size_t processedChars = 0; - val = std::stoull(token, &processedChars, 0); - if (processedChars != token.length()) - return nullptr; - } - catch (...) { return nullptr; } return next; } }; @@ -93,6 +80,7 @@ struct ArgInfo<T, std::enable_if_t<std::is_floating_point_v<T>>> std::string token(args, Trinity::Impl::ChatCommands::tokenize(next)); try { + // @todo replace this once libc++ supports double args to from_chars for required minimum size_t processedChars = 0; val = std::stold(token, &processedChars); if (processedChars != token.length()) @@ -103,16 +91,16 @@ struct ArgInfo<T, std::enable_if_t<std::is_floating_point_v<T>>> } }; -// string +// string_view template <> -struct ArgInfo<std::string, void> +struct ArgInfo<std::string_view, void> { - static char const* TryConsume(std::string& val, char const* args) + static char const* TryConsume(std::string_view& val, char const* args) { char const* next = args; if (size_t len = Trinity::Impl::ChatCommands::tokenize(next)) { - val.assign(args, len); + val = std::string_view(args, len); return next; } else @@ -120,19 +108,33 @@ struct ArgInfo<std::string, void> } }; +// string +template <> +struct ArgInfo<std::string, void> +{ + static char const* TryConsume(std::string& val, char const* args) + { + std::string_view view; + args = ArgInfo<std::string_view>::TryConsume(view, args); + if (args) + val.assign(view); + return args; + } +}; + // wstring template <> struct ArgInfo<std::wstring, void> { static char const* TryConsume(std::wstring& val, char const* args) { - std::string utf8Str; - char const* ret = ArgInfo<std::string>::TryConsume(utf8Str, args); + std::string_view utf8view; + char const* ret = ArgInfo<std::string_view>::TryConsume(utf8view, args); if (!ret) return nullptr; - if (!Utf8toWStr(utf8Str, val)) + if (!Utf8toWStr(utf8view, val)) return nullptr; return ret; diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp index a3bb2ce09e3..47f402d8122 100644 --- a/src/server/scripts/Commands/cs_go.cpp +++ b/src/server/scripts/Commands/cs_go.cpp @@ -441,7 +441,7 @@ public: return DoTeleport(handler, loc); } - static bool HandleGoInstanceCommand(ChatHandler* handler, std::vector<std::string> const& labels) + static bool HandleGoInstanceCommand(ChatHandler* handler, std::vector<std::string_view> labels) { if (labels.empty()) return false; @@ -453,7 +453,7 @@ public: uint32 count = 0; std::string const& scriptName = sObjectMgr->GetScriptName(pair.second.ScriptId); char const* mapName = ASSERT_NOTNULL(sMapStore.LookupEntry(pair.first))->MapName[handler->GetSessionDbcLocale()]; - for (auto const& label : labels) + for (std::string_view label : labels) if (StringContainsStringI(scriptName, label)) ++count; @@ -526,7 +526,7 @@ public: return false; } - static bool HandleGoBossCommand(ChatHandler* handler, std::vector<std::string> const& needles) + static bool HandleGoBossCommand(ChatHandler* handler, std::vector<std::string_view> needles) { if (needles.empty()) return false; @@ -543,7 +543,7 @@ public: uint32 count = 0; std::string const& scriptName = sObjectMgr->GetScriptName(data.ScriptID); - for (auto const& label : needles) + for (std::string_view label : needles) if (StringContainsStringI(scriptName, label) || StringContainsStringI(data.Name, label)) ++count; |