Понадобился мне тут сабж, и после дня ковыряний появился вопрос - это вообще возможно? Ситуация такая: CLI приложение, у него есть файл данных жёстко в UTF-8, также оно должно читать/писать пользовательские данные (думается, в его локали), а внутри работать со строками посимвольно + tolower/toupper + какая-никакая сортировка.
Как я понял, «C++» way - использовать эти locale и facets, только нигде по ним нет нормальной документации. Во всех примерах конвертят (через facet шототам .wider) ASCII из char* в wchar_t* - замечательно но только если в char* UTF8 то конвертит оно по байтам а не по символам. Это во-первых. Во-вторых, оно зависит от этого долбаного setlocale, а мне нахрен не упёрлось чтобы конвертация между utf8 и широким форматом как-то зависела от локали. C++'ного преобразования регистра нет, конвертим строки через towlower/towupper, что тоже с какого-то хрена зависит от локали. Сишный way с mbstowcs завист от локали аналогично. Кое-где советуют писать свою utf8 локаль или брать из буста с хитрыми хаками по переопределению namespace'ов.
Порыскал по интернету, нашёл замечательную библиотечку http://slonik-v-domene.livejournal.com/17731.html?thread=93507 как я понял utf8<->wide + lower/upper, безо всяких идиотских локалей. Там, правда, уродский сишный интерфейс с кучей аллокаций, но это не проблема переписать. Также для широких символов там используется не wchar_t, а unsigned int, а это уже не попихаешь в в wcout.
Ещё есть ICU (с совершенно ублюдской документацией) и, в конце концов iconv (хотя я бы предпочёл отказаться от внешних библиотек вообще).
Ещё есть новые литералы и char16_t/char32_t в C++11.
Итого - всего много, но ничего нормально не работает. Как быть?
Предполагаю что правильнее всего было бы разобраться с C++ локалями/фасетами и написать свои классы для utf8 и возможно utf32 с возможностью конвертации между ними, а для последнего case и сортировку. Однако нужна вменяемая документация на то как оно работает и вообще что эти фасеты значат. Другой вариант - сделать basic_string<int32_t> и написать для него функции конвертации в/из string (с utf8) и tolower/toupper и забыть про этот ад. Общение с пользователем оставить только в utf8.