Yet another C++ strings library implementation
Go to file
orefkov 4786bb4c81
Create cmake-multi-platform.yml
2025-11-11 12:03:37 +03:00
.github/workflows Create cmake-multi-platform.yml 2025-11-11 12:03:37 +03:00
bench - Исправлено поведение при получении подстроки, если from отрицательное число, большее по модулю длины строки. В этом случае подстрока берётся с начала строки. 2025-11-09 20:07:23 +03:00
cmake - Исправлено поведение при получении подстроки, если from отрицательное число, большее по модулю длины строки. В этом случае подстрока берётся с начала строки. 2025-11-09 20:07:23 +03:00
docs - Сделан workaround бага в MSVC, когда он не иногда плохо умеет в consteval 2025-08-10 13:01:39 +03:00
for_debug First commit 2025-08-07 13:44:02 +03:00
include/simstr Исправлен тип возвращаемого значения в hashStrMap::at 2025-11-10 20:35:35 +03:00
src First commit 2025-08-07 13:44:02 +03:00
tests Исправлен тип возвращаемого значения в hashStrMap::at 2025-11-10 20:35:35 +03:00
.clang-format First commit 2025-08-07 13:44:02 +03:00
.clang-tidy First commit 2025-08-07 13:44:02 +03:00
.clangd First commit 2025-08-07 13:44:02 +03:00
.editorconfig First commit 2025-08-07 13:44:02 +03:00
.gitattributes First commit 2025-08-07 13:44:02 +03:00
.gitignore First commit 2025-08-07 13:44:02 +03:00
CMakeLists.txt Исправил url 2025-11-11 11:52:42 +03:00
CMakePresets.json First commit 2025-08-07 13:44:02 +03:00
LICENSE First commit 2025-08-07 13:44:02 +03:00
readme.md Дополнил документацию 2025-11-10 12:18:00 +03:00

readme.md

simstr - библиотека строковых объектов и функций

Версия 1.0.

В этой библиотеке содержится реализация нескольких видов строковых объектов и различных алгоритмов для работы со строками.

Цель библиотеки - сделать работу со строками в С++ такой же простой и лёгкой, как во множестве других языков, особенно скриптовых, но при этом сохранив оптимальность и производительность на уровне С и C++, и даже улучшив их.

Не секрет, что работа со строками в С++ зачастую доставляет боль. Класс std::string часто неудобен либо неэффективен. Многих функций, обычно необходимых при работе со строками, просто нет, и их каждому приходится писать самому.

Эта библиотека не делалась как универсальный комбайн, который "может всё", я реализовывал то, что мне приходилось использовать в работе, стараясь сделать это наиболее эффективным способом, и скромно надеюсь, что кое-что у меня получилось и пригодится другим людям, либо напрямую, либо как источник идей.

Библиотека не претендует на роль "поменял хедер и всё заработало лучше". Многие методы я старался делать совместимыми с std::string и std::string_view, но особо с этим не заморачивался. Переписывание старого кода на работу с simstr потребует некоторых усилий, но уверяю, что они окупятся. А новый код писать с её применением легко и доставляет удовольствие :)

Основное отличие simstr от std::string - для работы со строками используется не единый универсальный класс, а несколько видов объектов, каждый из которых хорош для своих целей, и при этом хорошо взаимодействующих друг с другом. Если вы активно использовали std::string_view и понимали, в чём его преимущество и недостатки по сравнению с std::string, то подход simstr вам также будет понятен.

Основные возможности библиотеки

  • Строки char, char16_t, char32_t, wchar_t.
  • Прозрачное преобразование строк из одного типа символов в другой, с автоматической конвертацией между UTF-8, UTF-16, UTF-32, используя simdutf.
  • Расширяемая система "Строковых выражений". Позволяет эффективно реализовать преобразование и сложение (конкатенацию) строк, литералов, чисел и возможно других объектов.
  • Строковые функции:
    • Получение подстрок.
    • Поиск подстрок и символов - с начала или с конца строки.
    • Различный тримминг строк - справа, слева, везде, по пробельным символам, по заданным символам.
    • Замена подстрок.
    • Замена набора символов на набор соответствующих подстрок.
    • Слияние (join) контейнеров строк в единую строку, с заданием разделителей и опций - "пропускать пустые", "разделитель после последней".
    • Разбиение (split) строк на части по заданному разделителю. Разбиение возможно сразу в контейнер со строками, либо вызовом функтора для каждой подстроки, либо путем итерации с помощью итератора Splitter.
  • Интеграция с функциями форматирования format и sprintf (с автоматическим увеличением буфера). Форматирование возможно для строк char, wchar_t и строк, совместимых с wchar_t по размеру. То есть под Windows это char16_t, под Linux - char32_t. Писать свою библиотеку форматирования не входило в мои замыслы.
  • Парсинг целых чисел с возможностью "тонкой" настройки при компиляции - можно задавать опции проверки переполнения, пропуск пробельных символов, конкретное основание счисления либо автовыбор по префиксам 0x, 0, 0b, 0o, допустимость знака +. Парсинг реализован для всех видов строк и символов.
  • Парсинг double пока реализован вызовом стандартной библиотеки и работает только для строк char, wchar_t и совместимых с wchar_t по размеру типов.
  • Содержится минимальная поддержка Unicode при преобразовании upper, lower и регистро-независимом сравнении строк. Работает только для символов первой плоскости Unicode (до 0xFFFF), а при смене регистра не учитываются случаи, когда один code point может преобразовываться в несколько, то есть преобразование регистра символов соответствует std::towupper, std::towlower для unicode локали, только быстрее и может работать с любым видом символов.
  • Реализован hash map для ключей строкового типа, на базе std::unordered_map, с возможностью более эффективного хранения и сравнения ключей по сравнению с ключами std::string. Поддерживается возможность регистро-независимого сравнения ключей (Ascii или минимальный Unicode (см. предыдущий пункт)).

Основные объекты библиотеки

  • simple_str<K> - самая простая строка (или кусок строки), иммутабельная, не владеющая, аналог std::string_view.
  • simple_str_nt<K> - то же самое, только заявляет, что заканчивается 0. Для работы со сторонними C-API.
  • sstring<K> - shared string, иммутабельная, владеющая, с разделяемым буфером символов, поддержка SSO.
  • lstring<K, N> - local string, мутабельная, владеющая, с задаваемым размером SSO буфера.

Статьи

Использование

simstr состоит из трёх заголовочных файлов и двух исходников. Можно подключать как CMake проект через add_subdirectory (библиотека simstr), можно просто включить файлы в свой проект. Для сборки также требуется simdutf, (уже подключена к репозитарию как git submodule).

Для работы simstr требуется компилятор стандарта не ниже С++20 - используются концепты и std::format. Работа проверялась под Windows на MSVC-19 и Clang-19, под Linux - на GCC-13 и Clang-21. Также проверялась работа в WASM, сборка в Emscripten 4.0.6, Clang-21.

Бенчмарки

Бенчмарки производятся с использованием фреймворка Google benchmark. Постарался сделать замеры для наиболее типичных операций, встречающихся в обычной работе. Я проводил замеры на своём оборудовании, под Windows и Linux (в WSL), с использованием компиляторов MSVC, Clang, GCC. Сторонние результаты приветствуются. Также проводил замеры в WASM, сборка в Emscripten. Обращаю внимание, что под WASM в Emscripten собирается 32-битная сборка, а значит, размеры буферов SSO в объектах меньше.

Примеры использования

Пока отдельных примеров использования не подготовлено, можно посмотреть тексты тестов, бенчмарков, и утилиты подготовки html из результатов бенчмарков. Также simstr используется в моём проекте v8sqlite

Сгенерированная документация

Находится здесь