# simstr - библиотека строковых объектов и функций [![CMake on multiple platforms](https://github.com/orefkov/simstr/actions/workflows/cmake-multi-platform.yml/badge.svg)](https://github.com/orefkov/simstr/actions/workflows/cmake-multi-platform.yml) Версия 1.2.5. On English | По-английски В этой библиотеке содержится реализация нескольких видов строковых объектов и различных алгоритмов для работы со строками. Цель библиотеки - сделать работу со строками в С++ такой же простой и лёгкой, как во множестве других языков, особенно скриптовых, но при этом сохранив оптимальность и производительность на уровне С и 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](https://github.com/simdutf/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 буфера. ## Статьи - [Обзор и введение](docs/overview_ru.md) - [Обзорная статья на Хабре](https://habr.com/ru/articles/935590) - [Описание применяемой техники "Expression Templates"](https://habr.com/ru/articles/936468/) ## Использование `simstr` состоит из трёх заголовочных файлов и двух исходников. Можно подключать как CMake проект через `add_subdirectory` (библиотека `simstr`), можно просто включить файлы в свой проект. Для сборки также требуется [simdutf](https://github.com/simdutf/simdutf) (при использовании CMake скачивается автоматически). Для работы `simstr` требуется компилятор стандарта не ниже С++20 - используются концепты и std::format. Работа проверялась под Windows на MSVC-19 и Clang-19, под Linux - на GCC-13 и Clang-21. Также проверялась работа в WASM, сборка в Emscripten 4.0.6, Clang-21. ## Удобная отладка Вместе с библиотекой поставляются два файла, делающие просмотр simstr строковых объектов в отладчиках более удобным.\ Более подробно описано [здесь](for_debug/readme_ru.md). ## Бенчмарки Бенчмарки производятся с использованием фреймворка [Google benchmark](https://github.com/google/benchmark). Постарался сделать замеры для наиболее типичных операций, встречающихся в обычной работе. Я проводил замеры на своём оборудовании, под Windows и Linux (в WSL), с использованием компиляторов MSVC, Clang, GCC. Сторонние результаты приветствуются. Также проводил замеры в WASM, сборка в Emscripten. Обращаю внимание, что под WASM в Emscripten собирается 32-битная сборка, а значит, размеры буферов SSO в объектах меньше. - [Исходный код бенчмарков](bench/bench_str.cpp) - [Результаты бенчмарков](https://snegopat.ru/simstr/results.html) ## Примеры использования Пока отдельных примеров использования не подготовлено, можно посмотреть тексты [тестов](https://github.com/orefkov/simstr/blob/main/tests/test_str.cpp), [бенчмарков](https://github.com/orefkov/simstr/blob/main/bench/bench_str.cpp), и [утилиты подготовки html](https://github.com/orefkov/simstr/blob/main/bench/process_result.cpp) из результатов бенчмарков. Также simstr используется в моих проектах: - [simjson](https://github.com/orefkov/simjson) - библиотека для простой работы с JSON с использованием строк simstr. - [simrex](https://github.com/orefkov/simrex) - обёртка для работы с регулярными выражениями [Oniguruma](https://github.com/kkos/oniguruma) с использованием строк simstr. - [v8sqlite](https://github.com/orefkov/v8sqlite) - внешняя компонента для 1С-Предприятия V8 для работы с sqlite. ## Сгенерированная документация [Находится здесь](https://snegopat.ru/simstr/docs_ru/)