From af5c5a994b90a27e16ef6f2f5044e096269e4217 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 27 Oct 2021 13:01:37 -0400
Subject: SL-16207: Update llstring.h handling of different string types.

In llpreprocessor.h, consider the case of clang on Windows: #define
LL_WCHAR_T_NATIVE there as well as for the Microsoft compiler with /Zc:wchar_t
switch.

In stdtypes.h, inject a LLWCHAR_IS_WCHAR_T symbol to allow the preprocessor to
make decisions about when the types are identical.

llstring.h's conversion logic deals with three types of wide strings
(LLWString, std::wstring and utf16string) based on three types of wide char
(llwchar, wchar_t and U16, respectively). Sometimes they're three distinct
types, sometimes wchar_t is identical to llwchar and sometimes wchar_t is
identical to U16. Rationalize the three cases using ll_convert_u16_alias() and
new ll_convert_wstr_alias() macros.

stringize.h was directly calling wstring_to_utf8str() and utf8str_to_wstring(),
which was producing errors with VS 2019 clang since there isn't actually a
wstring_to_utf8str(std::wstring) overload. Use ll_convert<std::string>()
instead, since that redirects to the relevant ll_convert_wide_to_string()
function. (And now you see why we've been trying to migrate to the uniform
ll_convert<target>() wrapper!) Similarly, call ll_convert<std::wstring>()
instead of a two-step conversion from utf8str_to_wstring(), producing LLWString,
then a character-by-character copy from LLWString to std::wstring. That
isn't even correct: on Windows, we should be encoding from UTF32 to UTF16.
---
 indra/llcommon/stringize.h | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

(limited to 'indra/llcommon/stringize.h')

diff --git a/indra/llcommon/stringize.h b/indra/llcommon/stringize.h
index 38dd198ad3..31a114f167 100644
--- a/indra/llcommon/stringize.h
+++ b/indra/llcommon/stringize.h
@@ -52,7 +52,7 @@ std::basic_string<CHARTYPE> gstringize(const T& item)
  */
 inline std::string stringize(const std::wstring& item)
 {
-    return wstring_to_utf8str(item);
+    return ll_convert<std::string>(item);
 }
 
 /**
@@ -72,8 +72,7 @@ inline std::wstring wstringize(const std::string& item)
 {
     // utf8str_to_wstring() returns LLWString, which isn't necessarily the
     // same as std::wstring
-    LLWString s(utf8str_to_wstring(item));
-    return std::wstring(s.begin(), s.end());
+    return ll_convert<std::wstring>(item);
 }
 
 /**
@@ -146,11 +145,9 @@ void destringize_f(std::basic_string<CHARTYPE> const & str, Functor const & f)
  * std::istringstream in(str);
  * in >> item1 >> item2 >> item3 ... ;
  * @endcode
- * @NOTE - once we get generic lambdas, we shouldn't need DEWSTRINGIZE() any
- * more since DESTRINGIZE() should do the right thing with a std::wstring. But
- * until then, the lambda we pass must accept the right std::basic_istream.
  */
-#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::istream& in){in >> EXPRESSION;}))
-#define DEWSTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::wistream& in){in >> EXPRESSION;}))
+#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](auto& in){in >> EXPRESSION;}))
+// legacy name, just use DESTRINGIZE() going forward
+#define DEWSTRINGIZE(STR, EXPRESSION) DESTRINGIZE(STR, EXPRESSION)
 
 #endif /* ! defined(LL_STRINGIZE_H) */
-- 
cgit v1.2.3