Здрасьте. Чтобы не было путаницы в терминологии - под графемой понимаю что-то рисуемое на экране, занимаемое ровно одно знакоместо. Нужен алгоритм, который принимает на вход utf-8 строку и выдаёт на выходе число, которое равно количеству знакомест, которые занимает данная строка будучи отрисованной в терминале.
Но тут подстава со всякими управляющими символами, например Tab, котороый займет некоторое число знакомест, лазить в кишках terminfo для определения этого числа я точно не хочу. Решил поступить проще - итерироваться по символам и проверять является ли символ управляющим и если да, то менять его на пробел. И вот здесь встает вопрос - есть ли управляющие символы выше ASCII диапазона, которые могуть выдать что-то в терминал занимающее более одного знакоместа? Т.е. речь идёт о том, что делать ли std::iscntrl(char_sym, get_locale()) напрямую или конвертить предварительно всю последовательность в wchar_t и уже потом тестить. Естественно, что первое проще, а может второе и вовсе смысла не имеет. Управляющие символы там точно есть (U+2028, например), но рисуется в терминале одним знакоместом.
Я уже почти созрел до того, чтобы закрыть для себя вопрос юникода навсегда и остановиться лишь на в ASCII в софте, по крайней мере до момента, пока не появится адекватная либа, а не ICU. Была зыбкая надежда на boost.locale, но оказалось, что тот же U+2028 она не считет управляющим (тогда как локаль созданная дефолтными с++ средствами считает)
wchar_t w = L'\u2028';
cout << std::boolalpha
<< std::iscntrl(w, boost::locale::generator()("en_US.UTF-8")) << endl
<< std::iscntrl(w, std::locale("en_US.UTF-8")) << endl;
$ ./a.out
false
true
В общем вопросы к ней появились.