diff --git a/common/utf.h b/common/utf.h index 41e556f8..eafcea0d 100644 --- a/common/utf.h +++ b/common/utf.h @@ -28,12 +28,52 @@ extern size_t uiprivUTF16UTF8Count(const uint16_t *s, size_t nElem); #ifdef __cplusplus } -// Provide overloads on Windows for using these functions with wchar_t and WCHAR when wchar_t is a keyword in C++ mode (the default). -// Otherwise, you'd need to cast to pass a wchar_t pointer, WCHAR pointer, or equivalent to these functions. -// We use __wchar_t to be independent of the setting; see https://blogs.msdn.microsoft.com/oldnewthing/20161201-00/?p=94836 (ironically posted one day after I initially wrote this code!). -// TODO check this on MinGW-w64 +// TODO sync this back to upstream (need copyright clearance first) + +// On Windows, wchar_t is equivalent to uint16_t, but C++ requires +// wchar_t to be a completely distinct type. These overloads allow +// passing wchar_t pointers directly into these functions from C++ +// on Windows. Otherwise, you'd need to cast to pass a wchar_t +// pointer, WCHAR pointer, or equivalent to these functions. +// +// This does not apply to MSVC because the situation there is +// slightly more complicated; see below. +#if defined(_WIN32) && !defined(_MSC_VER) + +inline size_t uiprivUTF16EncodeRune(uint32_t rune, wchar_t *encoded) +{ + return uiprivUTF16EncodeRune(rune, reinterpret_cast(encoded)); +} + +inline const wchar_t *uiprivUTF16DecodeRune(const wchar_t *s, size_t nElem, uint32_t *rune) +{ + const uint16_t *ret; + + ret = uiprivUTF16DecodeRune(reinterpret_cast(s), nElem, rune); + return reinterpret_cast(ret); +} + +inline size_t uiprivUTF16RuneCount(const wchar_t *s, size_t nElem) +{ + return uiprivUTF16RuneCount(reinterpret_cast(s), nElem); +} + +inline size_t uiprivUTF16UTF8Count(const wchar_t *s, size_t nElem) +{ + return uiprivUTF16UTF8Count(reinterpret_cast(s), nElem); +} + +#endif + +// This is the same as the above, except that with MSVC, whether +// wchar_t is a keyword or not is controlled by a compiler option! +// (At least with gcc, this is not the case; thanks redi in +// irc.freenode.net/#gcc.) We use __wchar_t to be independent of +// the option; see https://blogs.msdn.microsoft.com/oldnewthing/20161201-00/?p=94836 +// (ironically posted one day after I initially wrote this code!). +// TODO should defined(_WIN32) be used too? // TODO check this under /Wall -// TODO C-style casts enough? or will that fail in /Wall? +// TODO are C-style casts enough? or will that fail in /Wall? // TODO same for UniChar/unichar on Mac? if both are unsigned then we have nothing to worry about #if defined(_MSC_VER)