Как прописать u32string (char32_t) в определенной локали?

В Windows с Visual Studio 2017 я могу использовать следующий код в верхнем регистре u32string (который основан на char32_t):

#include <locale>
#include <iostream>
#include <string>

void toUpper(std::u32string& u32str, std::string localeStr)
{
std::locale locale(localeStr);

for (unsigned i = 0; i<u32str.size(); ++i)
u32str[i] = std::toupper(u32str[i], locale);
}

То же самое не работает с macOS и XCode.
Я получаю такие ошибки:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__locale:795:44: error: implicit instantiation of undefined template 'std::__1::ctype<char32_t>'
return use_facet<ctype<_CharT> >(__loc).toupper(__c);

Есть ли портативный способ сделать это?

0

Решение

Я нашел решение:

Вместо того, чтобы использовать std::u32string Я сейчас использую std::string с utf8 кодирование.
Преобразование из std::u32string в std::string (utf8) можно сделать через utf8-cpp: http://utfcpp.sourceforge.net/

Нужно конвертировать utf8 строка в std::wstring (так как std::toupper не реализован на всех платформах для std::u32string).

void toUpper(std::string& str, std::string localeStr)
{
//unicode to wide string converter
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;

//convert to wstring (because std::toupper is not implemented on all platforms for u32string)
std::wstring wide = converter.from_bytes(str);

std::locale locale;

try
{
locale = std::locale(localeStr);
}
catch(const std::exception&)
{
std::cerr << "locale not supported by system: " << localeStr << " (" << getLocaleByLanguage(localeStr) << ")" << std::endl;
}

auto& f = std::use_facet<std::ctype<wchar_t>>(locale);

f.toupper(&wide[0], &wide[0] + wide.size());

//convert back
str = converter.to_bytes(wide);
}

Замечания:

  • На винде localeStr должно быть что-то вроде этого: en, de, fr
  • В других системах: localeStr должно быть de_DE, fr_FR, en_US
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]