Iteração de plataforma cruzada da cadeia de caracteres Unicode (contando Graphemes usando ICU)

Eu quero iterarcada personagem de uma sequência Unicode,tratando cada par substituto e combinando a sequência de caracteres como uma única unidade (um grafema).

Exemplo

O texto "नमस्ते" é composto pelos pontos de código:U+0928, U+092E, U+0938, U+094D, U+0924, U+0947, das quais,U+0938 eU+0947 estãocombinando marcas.

static void Main(string[] args)
{
    const string s = "नमस्ते";

    Console.WriteLine(s.Length); // Ouptuts "6"

    var l = 0;
    var e = System.Globalization.StringInfo.GetTextElementEnumerator(s);
    while(e.MoveNext()) l++;
    Console.WriteLine(l); // Outputs "4"
}

Então, temos isso no .NET. Também temos Win32CharNextW()

#include <Windows.h>
#include <iostream>
#include <string>

int main()
{
    const wchar_t * s = L"नमस्ते";

    std::cout << std::wstring(s).length() << std::endl; // Gives "6"

    int l = 0;
    while(CharNextW(s) != s)
    {
        s = CharNextW(s);
        ++l;
    }

    std::cout << l << std::endl; // Gives "4"

    return 0;
}
Pergunta, questão

As duas maneiras que conheço são específicas da Microsoft. Existemportátil maneiras de fazer isso?

Eu ouvi sobre a UTI, mas não consegui encontrar algo relacionado rapidamente (UnicodeString(s).length() ainda dá 6). Seria uma resposta aceitável apontar para a função / módulo relacionado na UTI.Como o C ++ não tem noção de Unicode, uma biblioteca leve de plataforma cruzada para lidar com esses problemas seria uma resposta aceitável.Edit: Resposta correta usando ICU

@McDowell deu a dica de usarBreakIterator da UTI, que eu acho que pode ser considerado o padrão de plataforma cruzada de fato para lidar com o Unicode. Aqui está um código de exemplo para demonstrar seu uso (já que exemplos sãosurpreendentemente raro):

#include <unicode/schriter.h>
#include <unicode/brkiter.h>

#include <iostream>
#include <cassert>
#include <memory>

int main()
{
    const UnicodeString str(L"नमस्ते");

    {
        // StringCharacterIterator doesn't seem to recognize graphemes
        StringCharacterIterator iter(str);
        int count = 0;
        while(iter.hasNext())
        {
            ++count;
            iter.next();
        }
        std::cout << count << std::endl; // Gives "6"
    }

    {
        // BreakIterator works!!
        UErrorCode err = U_ZERO_ERROR;
        std::unique_ptr<BreakIterator> iter(
            BreakIterator::createCharacterInstance(Locale::getDefault(), err));
        assert(U_SUCCESS(err));
        iter->setText(str);

        int count = 0;
        while(iter->next() != BreakIterator::DONE) ++count;
        std::cout << count << std::endl; // Gives "4"
    }

    return 0;
}

questionAnswers(3)

yourAnswerToTheQuestion