Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Вычисление длины utf-8 строки в compile time / 25 сообщений из 76, страница 1 из 4
20.07.2020, 20:20
    #39982007
petrav
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
Как думаете нормально? Работать будет? :)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
inline constexpr
size_t c_strlen(char const *start, size_t const maxBuffSize)
{
    char const *end = start;
    while (*end != '\0')
    {
        ++end;

        if (end - start >= maxBuffSize)
        {
            throw std::runtime_error("The string is too long.");
        }
    }

    size_t charCount = 0;
    while (start < end)
    {
        byte const ch = static_cast<byte>(*start);
        size_t chSize = {};

        if      ((ch & 0x80) == 0x00)   chSize = 1;
        else if ((ch & 0xE0) == 0xC0)   chSize = 2;
        else if ((ch & 0xF0) == 0xE0)   chSize = 3;
        else if ((ch & 0xF8) == 0xF0)   chSize = 4;
        else throw std::runtime_error("Invalid UTF-8 char.");

        if (chSize > end - start)
        {
            throw std::runtime_error("UTF-8 string too short.");
        }

        for (size_t i = 1; i < chSize; ++i)
        {
            if ((start[i] & 0xC0) != 0x80)
            {
                throw std::runtime_error("Expected continuation UTF-8 byte.");
            }
        }

        ++charCount;
        start += chSize;
    }

    return charCount;
}
...
Рейтинг: 0 / 0
21.07.2020, 10:45
    #39982150
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
petrav, так ты скомпилируй и посмотри! :)
...
Рейтинг: 0 / 0
21.07.2020, 11:28
    #39982160
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
petrav, к чему вообще весь этот зоопарк, если тебе, всего лишь, надо узнать кол-во байт литерала?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
#include <cstdlib>
#include <stdio.h>

using namespace std;

static constexpr char test[] = u8"Тестовое сообщение";

int main(int argc, char** argv)
{
  printf("\r\n%zu\r\n", sizeof(test));
  return 0;
}

Результат, как и ожидалось, "36".
...
Рейтинг: 0 / 0
21.07.2020, 12:07
    #39982176
petrav
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
rdb_dev
petrav, к чему вообще весь этот зоопарк, если тебе, всего лишь, надо узнать кол-во байт литерала?

Не количество байт, а количество символов. И не обязательно у литерала. Compile time только по возможности.

Я, конечно, тестировал на русских буквах и иероглифах. Но я ведь программировал по мотивам кода со стек-оферфлоу. И там было приписано, что реализация наивная. Поэтому и спрашиваю, может можно улучшить.
...
Рейтинг: 0 / 0
21.07.2020, 12:56
    #39982185
AmKad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
Я когда-то взял не глядя функцию UTF2Unicode с хабра https://habr.com/ru/post/282191/
Правда параметр заменил на
Код: plaintext
1.
const /*unsigned*/ char* txt


Для подсчета символов тоже подойдет. На иероглифах не пробовал.
...
Рейтинг: 0 / 0
21.07.2020, 13:16
    #39982200
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
AmKad,
А какой смысл в символах считать? Это не универсально.
Может на знаки? Диакритические знаки? Кодовые точки, составные символы?
...
Рейтинг: 0 / 0
21.07.2020, 13:18
    #39982204
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
petrav,
Вот как-то так...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
#include <cstdlib>
#include <stdio.h>

using namespace std;


static constexpr char test[] = u8"Тестовое сообщение";

class utf8literal
{
  template <typename T>
  static constexpr
  size_t bytes_per_u8char(T chr, bool start = true)
  {
    return (start && !(chr & 0x80))
        ? 1
        : (chr & 0x80)
            ? 1 + bytes_per_u8char(chr << 1, false)
            : 0;
  }

  template <typename T, size_t D>
  static constexpr
  size_t calc_length(T (&a)[D], size_t i = 0)
  {
    return (i < D)
        ? 1 + calc_length(a, i + bytes_per_u8char(a[i]))
        : 0;
  }

public:

  template <typename T, size_t D>
  static constexpr
  size_t length(T (&a)[D])
  {
    return calc_length<T, D>(a) - 1;
  }
};

int main(int argc, char** argv)
{
  printf("\r\n%zu\r\n", utf8literal::length(test));
  return 0;
}

Только не забудь впихнуть static_assert для (T != char).
...
Рейтинг: 0 / 0
21.07.2020, 13:25
    #39982205
AmKad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
PetroNotC Sharp
А какой смысл в символах считать? Это не универсально.
Может на знаки? Диакритические знаки? Кодовые точки, составные символы?
Лично мне эта функция нужна для целей, описанных в статье - для рендеринга. И длину я считаю не в символах, в пикселях. Но алгоритм можно заюзать и для подсчета символов, например, для выравнивания вывода моноширинного шрифта в консоли.
...
Рейтинг: 0 / 0
21.07.2020, 13:27
    #39982206
petrav
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
rdb_dev
petrav,
Вот как-то так...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
#include <cstdlib>
#include <stdio.h>

using namespace std;


static constexpr char test[] = u8"Тестовое сообщение";

class utf8literal
{
  template <typename T>
  static constexpr
  size_t bytes_per_u8char(T chr, bool start = true)
  {
    return (start && !(chr & 0x80))
        ? 1
        : (chr & 0x80)
            ? 1 + bytes_per_u8char(chr << 1, false)
            : 0;
  }

  template <typename T, size_t D>
  static constexpr
  size_t calc_length(T (&a)[D], size_t i = 0)
  {
    return (i < D)
        ? 1 + calc_length(a, i + bytes_per_u8char(a[i]))
        : 0;
  }

public:

  template <typename T, size_t D>
  static constexpr
  size_t length(T (&a)[D])
  {
    return calc_length<T, D>(a) - 1;
  }
};

int main(int argc, char** argv)
{
  printf("\r\n%zu\r\n", utf8literal::length(test));
  return 0;
}

Только не забудь впихнуть static_assert для (T != char).

Как-то у вас всё переусложнено, ИМХО. Я так понимаю тут подсчитываются лидирующие символы, а не лидирующие пропускаются.
...
Рейтинг: 0 / 0
21.07.2020, 13:39
    #39982217
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
petrav
Как-то у вас всё переусложнено, ИМХО.
Наоборот - всё до безобразия упрощено.

petrav
Я так понимаю тут подсчитываются лидирующие символы, а не лидирующие пропускаются.
Пропуск кол-ва байт символа определяется по старшим битам лидирующего байта символа, а в подсчёт попадают именно символы. Попробуй впихнуть в литерал между русскими символами те, что кодируются четырьмя байтами и почувствуй разницу. Ведь ты же хотел именно подсчёт символов, а не байт?
...
Рейтинг: 0 / 0
21.07.2020, 13:42
    #39982219
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
AmKad,
В пикселях же в winApi есть?
Типа getTextPoint.....
И там учитывается шрифт, выравнивание и куча всего.
...
Рейтинг: 0 / 0
21.07.2020, 13:46
    #39982225
AmKad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
PetroNotC Sharp
В пикселях же в winApi есть?
Может быть и есть, но winApi нет на ведроиде и яблоке.
...
Рейтинг: 0 / 0
21.07.2020, 13:51
    #39982226
petrav
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
rdb_dev
petrav
Как-то у вас всё переусложнено, ИМХО.
Наоборот - всё до безобразия упрощено.

petrav
Я так понимаю тут подсчитываются лидирующие символы, а не лидирующие пропускаются.
Пропуск кол-ва байт символа определяется по старшим битам лидирующего байта символа, а в подсчёт попадают именно символы. Попробуй впихнуть в литерал между русскими символами те, что кодируются четырьмя байтами и почувствуй разницу. Ведь ты же хотел именно подсчёт символов, а не байт?

Да символов. Попробовал, с моим кодом тоже всё работает.
...
Рейтинг: 0 / 0
21.07.2020, 14:03
    #39982239
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
petrav, enjoy! :)
...
Рейтинг: 0 / 0
21.07.2020, 14:05
    #39982240
petrav
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
rdb_dev
petrav, enjoy! :)

Правда у меня смесь русских букв и иероглифов (иероглифы в три байта).
...
Рейтинг: 0 / 0
21.07.2020, 14:05
    #39982241
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
petrav
Правда у меня смесь русских букв и иероглифов (иероглифы в три байта).
Для теста самое то!
...
Рейтинг: 0 / 0
21.07.2020, 14:29
    #39982253
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
AmKad
PetroNotC Sharp
В пикселях же в winApi есть?
Может быть и есть, но winApi нет на ведроиде и яблоке.

Блин, опять универсальность везде).
Тогда конечно.
А так там свои API есть
Типа:
getTextBounds
Added in API level 1
public void getTextBounds (String text,
int start,
int end,
Rect bounds)
...
Рейтинг: 0 / 0
21.07.2020, 15:21
    #39982270
AmKad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
PetroNotC Sharp,

Я стараюсь все, что можно сделать на перенесимом C++, делать на нем. Посчитать размер выводимой через openglES строки текста - задача не сложная. Завязываться на специфичное Java-API ради этого не хочется.
...
Рейтинг: 0 / 0
21.07.2020, 15:23
    #39982272
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
Осталась сущая мелочь: найти в С++ переносимые шрифты.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
21.07.2020, 15:30
    #39982279
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
AmKad,

У OpenGL разве не в Canvas. У которого есть Pаint. С длиной текста методом?
...
Рейтинг: 0 / 0
21.07.2020, 15:30
    #39982281
AmKad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
Dimitry Sibiryakov

Осталась сущая мелочь: найти в С++ переносимые шрифты.
Статья как раз о том, как сделать такой "шрифт" на основе SDF.
...
Рейтинг: 0 / 0
21.07.2020, 15:34
    #39982284
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
AmKad
Dimitry Sibiryakov

Осталась сущая мелочь: найти в С++ переносимые шрифты.
Статья как раз о том, как сделать такой "шрифт" на основе SDF.
и отрисовать попиксельно сглаживая) :))
Круто.
...
Рейтинг: 0 / 0
21.07.2020, 15:35
    #39982285
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
Глянул статью - опять игрушки.
Понятно.
...
Рейтинг: 0 / 0
21.07.2020, 15:36
    #39982287
AmKad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
PetroNotC Sharp
AmKad,

У OpenGL разве не в Canvas. У которого есть Pаint. С длиной текста методом?
Не знаю что такое canvas и paint. У openGL(ES) нет функций для вывода текста. Только многоугольники. В случае ES - треугольники. Вообще, если интересно покопаться в моем говнокоде и закидать меня помидорами, могу дать ссылку на репозиторий.
...
Рейтинг: 0 / 0
21.07.2020, 15:36
    #39982288
AmKad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычисление длины utf-8 строки в compile time
PetroNotC Sharp
Глянул статью - опять игрушки.
Понятно.
Да. Увы, на что-то серьезное я не способен
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Вычисление длины utf-8 строки в compile time / 25 сообщений из 76, страница 1 из 4
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]