mirror of https://github.com/orefkov/simstr.git
1.5.0.
This commit is contained in:
parent
620383a5a4
commit
35d2ea2ee8
|
|
@ -5,7 +5,7 @@ include(FetchContent)
|
|||
|
||||
project(
|
||||
simstr
|
||||
VERSION 1.4.0
|
||||
VERSION 1.5.0
|
||||
DESCRIPTION "Yet another modern C++ string library"
|
||||
HOMEPAGE_URL "https://github.com/orefkov/simstr"
|
||||
LANGUAGES CXX
|
||||
|
|
@ -116,7 +116,7 @@ if(SIMSTR_BUILD_TESTS)
|
|||
googletest
|
||||
# Specify the commit you depend on and update it regularly.
|
||||
URL https://github.com/google/googletest/archive/refs/tags/v1.17.0.zip
|
||||
FIND_PACKAGE_ARGS NAMES GTest 1.17.0
|
||||
FIND_PACKAGE_ARGS NAMES "GTest 1.17.0"
|
||||
)
|
||||
# For Windows: Prevent overriding the parent project's compiler/linker settings
|
||||
set(gtest_force_shared_crt FALSE CACHE BOOL "" FORCE)
|
||||
|
|
@ -134,7 +134,7 @@ function(GBencmark)
|
|||
googlebench
|
||||
# Specify the commit you depend on and update it regularly.
|
||||
URL https://github.com/google/benchmark/archive/refs/tags/v1.9.4.zip
|
||||
FIND_PACKAGE_ARGS NAMES benchmark 1.9.4
|
||||
FIND_PACKAGE_ARGS NAMES "benchmark 1.9.4"
|
||||
)
|
||||
set(BENCHMARK_ENABLE_TESTING OFF)
|
||||
set(BENCHMARK_ENABLE_LTO OFF)
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ PROJECT_NAME = "simstr"
|
|||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = 1.4.0
|
||||
PROJECT_NUMBER = 1.5.0
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewers a
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ PROJECT_NAME = "simstr"
|
|||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = 1.4.0
|
||||
PROJECT_NUMBER = 1.5.0
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewers a
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* (c) Проект "SimStr", Александр Орефков orefkov@gmail.com
|
||||
* ver. 1.0
|
||||
* ver. 1.5.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* (c) Проект "SimStr", Александр Орефков orefkov@gmail.com
|
||||
* ver. 1.4.0
|
||||
* ver. 1.5.0
|
||||
* Классы для работы со строками
|
||||
* (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com
|
||||
* ver. 1.4.0
|
||||
* ver. 1.5.0
|
||||
* Classes for working with strings
|
||||
*/
|
||||
|
||||
|
|
@ -314,7 +314,13 @@ public:
|
|||
return {};
|
||||
}
|
||||
#endif
|
||||
return impl_to_double(ptr, ptr + len);
|
||||
if constexpr (sizeof(K) == 1) {
|
||||
return impl_to_double((const char*)ptr, (const char*)ptr + len);
|
||||
} else if constexpr (sizeof(K) == 2) {
|
||||
return impl_to_double((const char16_t*)ptr, (const char16_t*)ptr + len);
|
||||
} else {
|
||||
return impl_to_double((const char32_t*)ptr, (const char32_t*)ptr + len);
|
||||
}
|
||||
}
|
||||
/*!
|
||||
* @ru @brief Преобразовать строку в double.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* ver. 1.4.0
|
||||
* ver. 1.5.0
|
||||
* (c) Проект "SimStr", Александр Орефков orefkov@gmail.com
|
||||
* База для строковых конкатенаций через выражения времени компиляции
|
||||
* (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com
|
||||
|
|
@ -3282,7 +3282,7 @@ public:
|
|||
return {};
|
||||
}
|
||||
double d{};
|
||||
if (std::from_chars(ptr, ptr + len, d).ec == std::errc{}) {
|
||||
if (std::from_chars((const u8s*)ptr, (const u8s*)ptr + len, d).ec == std::errc{}) {
|
||||
return d;
|
||||
}
|
||||
return {};
|
||||
|
|
@ -4477,32 +4477,20 @@ constexpr auto e_repl(A&& w, T&& p, X&& r) {
|
|||
|
||||
/*!
|
||||
* @ingroup StrExprs
|
||||
* @ru @brief Строковое выражение, генерирующее строку с заменой всех вхождений заданной подстроки.
|
||||
* @ru @brief Строковое выражение, генерирующее строку с заменой всех вхождений заданной подстроки на другую строку.
|
||||
* @tparam K - тип строки.
|
||||
* @details `e_repl` позволяет заменять только с использование строковых литералов.
|
||||
* В случае, когда искомая подстрока или строка замены не известны при компиляции, и задаются в runtime,
|
||||
* следует использовать этот тип, например:
|
||||
* @en @brief A string expression that generates a string replacing all occurrences of the given substring.
|
||||
* @en @brief A string expression that generates a string replacing all occurrences of the given substring to another string.
|
||||
* @tparam K - string type.
|
||||
* @details `e_repl` only allows replacement using string literals.
|
||||
* In the case when the required substring or replacement string is not known at compilation, and is set at runtime,
|
||||
* this type should be used, for example:
|
||||
* @~
|
||||
* ```cpp
|
||||
* stringa result = "<header>" + expr_replaced<u8s>{source, pattern, repl} + "</header>";
|
||||
* ```
|
||||
*/
|
||||
template<typename K, typename E = int>
|
||||
template<typename K>
|
||||
struct expr_replaced : expr_to_std_string<expr_replaced<K>> {
|
||||
using symb_type = K;
|
||||
using my_type = expr_replaced<K>;
|
||||
str_src<K> what;
|
||||
const str_src<K> pattern;
|
||||
mutable K* replStart;
|
||||
mutable size_t replLen;
|
||||
const str_src<K> repl;
|
||||
mutable find_all_container<FIND_CACHE_SIZE> matches_;
|
||||
mutable size_t last_;
|
||||
const E& expr;
|
||||
/*!
|
||||
* @ru @brief Конструктор.
|
||||
* @param w - исходная строка.
|
||||
|
|
@ -4513,20 +4501,17 @@ struct expr_replaced : expr_to_std_string<expr_replaced<K>> {
|
|||
* @param p - the searched substring.
|
||||
* @param r - replacement string.
|
||||
*/
|
||||
constexpr expr_replaced(str_src<K> w, str_src<K> p, const K* r, size_t rl, const E& e) : what(w), pattern(p), replStart(const_cast<K*>(r)), replLen(rl), expr(e) {}
|
||||
constexpr expr_replaced(str_src<K> w, str_src<K> p, str_src<K> r) : what(w), pattern(p), repl(r) {}
|
||||
|
||||
constexpr size_t length() const {
|
||||
size_t l = what.length(), plen = pattern.length();
|
||||
if constexpr (!std::is_same_v<E, int>) {
|
||||
replLen = expr.length();
|
||||
}
|
||||
if (!plen || plen == replLen) {
|
||||
size_t l = what.length(), plen = pattern.length(), rlen = repl.length();
|
||||
if (!plen || plen == rlen) {
|
||||
return l;
|
||||
}
|
||||
what.find_all_to(matches_, pattern.symbols(), plen, 0, FIND_CACHE_SIZE);
|
||||
if (matches_.added_) {
|
||||
last_ = matches_.positions_[matches_.added_ - 1] + plen;
|
||||
l += int(replLen - plen) * matches_.added_;
|
||||
l += int(rlen - plen) * matches_.added_;
|
||||
|
||||
if (matches_.added_ == FIND_CACHE_SIZE) {
|
||||
for (;;) {
|
||||
|
|
@ -4535,7 +4520,7 @@ struct expr_replaced : expr_to_std_string<expr_replaced<K>> {
|
|||
break;
|
||||
}
|
||||
last_ = next + plen;
|
||||
l += replLen - plen;
|
||||
l += rlen - plen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4545,8 +4530,8 @@ struct expr_replaced : expr_to_std_string<expr_replaced<K>> {
|
|||
return l;
|
||||
}
|
||||
constexpr K* place(K* ptr) const noexcept {
|
||||
size_t plen = pattern.length();
|
||||
if (plen == replLen) {
|
||||
size_t plen = pattern.length(), rlen = repl.length();
|
||||
if (plen == rlen) {
|
||||
const K* from = what.symbols();
|
||||
for (size_t start = 0; start < what.length();) {
|
||||
size_t next = what.find(pattern, start);
|
||||
|
|
@ -4556,17 +4541,8 @@ struct expr_replaced : expr_to_std_string<expr_replaced<K>> {
|
|||
size_t delta = next - start;
|
||||
ch_traits<K>::copy(ptr, from + start, delta);
|
||||
ptr += delta;
|
||||
if constexpr (std::is_same_v<E, int>) {
|
||||
ch_traits<K>::copy(ptr, replStart, replLen);
|
||||
} else {
|
||||
if (!replStart) {
|
||||
replStart = ptr;
|
||||
expr.place(replStart);
|
||||
} else {
|
||||
ch_traits<K>::copy(ptr, replStart, replLen);
|
||||
}
|
||||
}
|
||||
ptr += replLen;
|
||||
ch_traits<K>::copy(ptr, repl.symbols(), rlen);
|
||||
ptr += rlen;
|
||||
start = next + plen;
|
||||
}
|
||||
return ptr;
|
||||
|
|
@ -4581,21 +4557,12 @@ struct expr_replaced : expr_to_std_string<expr_replaced<K>> {
|
|||
for (size_t start = 0, offset = matches_.positions_[0], idx = 1; ;) {
|
||||
ch_traits<K>::copy(ptr, from + start, offset - start);
|
||||
ptr += offset - start;
|
||||
if constexpr (std::is_same_v<E, int>) {
|
||||
ch_traits<K>::copy(ptr, replStart, replLen);
|
||||
} else {
|
||||
if (!replStart) {
|
||||
replStart = ptr;
|
||||
expr.place(replStart);
|
||||
} else {
|
||||
ch_traits<K>::copy(ptr, replStart, replLen);
|
||||
}
|
||||
}
|
||||
ptr += replLen;
|
||||
ch_traits<K>::copy(ptr, repl.symbols(), rlen);
|
||||
ptr += rlen;
|
||||
start = offset + plen;
|
||||
if (start >= last_) {
|
||||
size_t tail = what.length() - last_;
|
||||
ch_traits<K>::copy(ptr, from + last_, tail);
|
||||
size_t tail = what.length() - start;
|
||||
ch_traits<K>::copy(ptr, from + start, tail);
|
||||
ptr += tail;
|
||||
break;
|
||||
} else {
|
||||
|
|
@ -4606,6 +4573,130 @@ struct expr_replaced : expr_to_std_string<expr_replaced<K>> {
|
|||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* @ingroup StrExprs
|
||||
* @ru @brief Строковое выражение, генерирующее строку с заменой всех вхождений заданной подстроки на строковое выражение.
|
||||
* @tparam K - тип строки.
|
||||
* @details Если искомая подстрока не найдена, то строковое выражение даже не вычисляется.
|
||||
* Затем при осуществлении замены строковое выражение вычисляется только один раз в место первой замены,
|
||||
* а в следующие места замен просто копируется символы из первого места. Это позволяет экономить память
|
||||
* и время, если вам надо сделать замену на какую-либо "сборную" строку.
|
||||
* @en @brief A string expression that generates a string replacing all occurrences of the given substring to string expression.
|
||||
* @tparam K - string type.
|
||||
* @details If the search substring is not found, the string expression is not even evaluated.
|
||||
* Then, when performing a replacement, the string expression is evaluated only once at the first replacement location,
|
||||
* and characters from the first location are simply copied to subsequent replacement locations. This saves memory
|
||||
* and time if you need to replace with some kind of "composite" string.
|
||||
*/
|
||||
template<typename K, StrExprForType<K> E>
|
||||
struct expr_replaced_e : expr_to_std_string<expr_replaced_e<K, E>> {
|
||||
using symb_type = K;
|
||||
using my_type = expr_replaced<K>;
|
||||
str_src<K> what;
|
||||
const str_src<K> pattern;
|
||||
mutable size_t replLen;
|
||||
mutable find_all_container<FIND_CACHE_SIZE> matches_;
|
||||
mutable size_t last_;
|
||||
const E& expr;
|
||||
/*!
|
||||
* @ru @brief Конструктор.
|
||||
* @param w - исходная строка.
|
||||
* @param p - искомая подстрока.
|
||||
* @param e - строковое выражение для замены.
|
||||
* @en @brief Constructor.
|
||||
* @param w - source string.
|
||||
* @param p - the searched substring.
|
||||
* @param e - string expression to replace.
|
||||
*/
|
||||
constexpr expr_replaced_e(str_src<K> w, str_src<K> p, const E& e) : what(w), pattern(p), expr(e) {}
|
||||
|
||||
constexpr size_t length() const {
|
||||
size_t l = what.length(), plen = pattern.length();
|
||||
if (!plen) {
|
||||
return l;
|
||||
}
|
||||
matches_.positions_[0] = what.find(pattern);
|
||||
if (matches_.positions_[0] == -1) {
|
||||
// Не нашли вхождений, нечего менять
|
||||
return l;
|
||||
}
|
||||
matches_.added_ = 1;
|
||||
// Вхождение есть, надо теперь получить длину замены
|
||||
replLen = expr.length();
|
||||
if (replLen == plen) {
|
||||
// Замена той же длины, общая длина не изменится
|
||||
return l;
|
||||
}
|
||||
what.find_all_to(matches_, pattern.symbols(), plen, matches_.positions_[0] + plen, FIND_CACHE_SIZE - 1);
|
||||
|
||||
last_ = matches_.positions_[matches_.added_ - 1] + plen;
|
||||
l += int(replLen - plen) * matches_.added_;
|
||||
|
||||
if (matches_.added_ == FIND_CACHE_SIZE) {
|
||||
for (;;) {
|
||||
size_t next = what.find(pattern.symbols(), plen, last_);
|
||||
if (next == str::npos) {
|
||||
break;
|
||||
}
|
||||
last_ = next + plen;
|
||||
l += replLen - plen;
|
||||
}
|
||||
}
|
||||
if (!l) {
|
||||
matches_.added_ = -1;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
constexpr K* place(K* ptr) const noexcept {
|
||||
if (matches_.added_ == 0) {
|
||||
// не было найдено вхождений
|
||||
return what.place(ptr);
|
||||
} else if (matches_.added_ == -1) {
|
||||
// Строка стала пустой
|
||||
return ptr;
|
||||
}
|
||||
size_t plen = pattern.length();
|
||||
const K* from = what.symbols();
|
||||
ch_traits<K>::copy(ptr, from, matches_.positions_[0]);
|
||||
ptr += matches_.positions_[0];
|
||||
const K* repl = ptr;
|
||||
expr.place((typename E::symb_type*)ptr);
|
||||
ptr += replLen;
|
||||
size_t start = matches_.positions_[0] + plen;
|
||||
|
||||
if (plen == replLen) {
|
||||
for (;;) {
|
||||
size_t next = what.find(pattern, start);
|
||||
if (next == str::npos) {
|
||||
break;
|
||||
}
|
||||
size_t delta = next - start;
|
||||
ch_traits<K>::copy(ptr, from + start, delta);
|
||||
ptr += delta;
|
||||
ch_traits<K>::copy(ptr, repl, replLen);
|
||||
ptr += replLen;
|
||||
start = next + plen;
|
||||
}
|
||||
} else {
|
||||
for (size_t idx = 1;;) {
|
||||
if (start >= last_) {
|
||||
break;
|
||||
}
|
||||
size_t next = idx < FIND_CACHE_SIZE ? matches_.positions_[idx++] : what.find(pattern, start);
|
||||
size_t delta = next - start;
|
||||
ch_traits<K>::copy(ptr, from + start, delta);
|
||||
ptr += delta;
|
||||
ch_traits<K>::copy(ptr, repl, replLen);
|
||||
ptr += replLen;
|
||||
start = next + plen;
|
||||
}
|
||||
}
|
||||
size_t tail = what.length() - start;
|
||||
ch_traits<K>::copy(ptr, from + start, tail);
|
||||
return ptr + tail;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* @ingroup StrExprs
|
||||
* @ru @brief Получить строковое выражение, генерирующее строку с заменой всех вхождений заданной подстроки.
|
||||
|
|
@ -4624,7 +4715,7 @@ template<StrSource A, typename K = src_str_t<A>, typename T, typename X>
|
|||
constexpr auto e_repl(A&& w, T&& p, X&& r) {
|
||||
str_src<K> pattern{std::forward<T>(p)};
|
||||
str_src<K> repl{std::forward<X>(r)};
|
||||
return expr_replaced<K, int>{get_str_src_from(std::forward<A>(w)), pattern, repl.str, repl.len, 0};
|
||||
return expr_replaced<K>{get_str_src_from(std::forward<A>(w)), pattern, repl};
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -4644,7 +4735,7 @@ template<StrSource A, typename K = src_str_t<A>, typename T, StrExprForType<K> E
|
|||
requires std::is_constructible_v<str_src<K>, T>
|
||||
constexpr auto e_repl(A&& w, T&& p, const E& expr) {
|
||||
str_src<K> pattern{std::forward<T>(p)};
|
||||
return expr_replaced<K, E>{get_str_src_from(std::forward<A>(w)), pattern, nullptr, 0, expr};
|
||||
return expr_replaced_e<K, E>{get_str_src_from(std::forward<A>(w)), pattern, expr};
|
||||
}
|
||||
|
||||
template<bool UseVectorForReplace>
|
||||
|
|
|
|||
17
readme.md
17
readme.md
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
[](https://github.com/orefkov/simstr/actions/workflows/cmake-multi-platform.yml)
|
||||
|
||||
Version 1.4.0.
|
||||
Version 1.5.0.
|
||||
|
||||
<span class="obfuscator"><a href="readme_ru.md">On Russian | По-русски</a></span>
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ If you actively used `std::string_view` and understood its advantages and disadv
|
|||
then the `simstr` approach will also be clear to you.
|
||||
|
||||
## Main features of the library
|
||||
When using only `#include "simstr\strexpr.h"`:
|
||||
When using only `#include "simstr/strexpr.h"`:
|
||||
- Support for working with strings `char`, `char8_t`, `char16_t`, `char32_t`, `wchar_t`.
|
||||
- Powerful and extensible *"String Expressions"* system.
|
||||
Allows you to efficiently implement the conversion and addition (concatenation) of strings, string literals, numbers (and possibly other objects),
|
||||
|
|
@ -65,6 +65,11 @@ When using only `#include "simstr\strexpr.h"`:
|
|||
- Merging (join) containers of strings into a single string, with specifying delimiters and options - "skip empty", "delimiter after last".
|
||||
- Splitting strings into parts by a specified delimiter. Splitting is possible immediately into a container with strings, or by calling a functor for
|
||||
each substring, or by iterating using the `Splitter` iterator.
|
||||
- Functions for modifying standard strings with string expressions:
|
||||
- str::append, str::prepend, str::insert, str::change - modify str::string with string expressions,
|
||||
for example, `str::append(text, "count = "_ss + count + " times")`.
|
||||
- str::replace - replaces occurrences of the searched substring with the replacement string or string expression.
|
||||
If the substring is not found, the string expression is not even evaluated.
|
||||
- Parsing integers with the possibility of "fine" tuning at compile time - you can set options for checking overflow,
|
||||
skipping whitespace characters, a specific base or auto-selection by prefixes `0x`, `0`, `0b`, `0o`,
|
||||
admissibility of the `+` sign. Parsing is implemented for all types of strings and characters.
|
||||
|
|
@ -277,9 +282,9 @@ When connecting only `strexpr.h` - the types `simple_str<K>` and `simple_str_nt<
|
|||
- [Description of the "Expression Templates" technique used](https://habr.com/ru/articles/936468/) (On Russian)
|
||||
|
||||
## Usage
|
||||
The library can be used partially, just by taking the file `"include\simstr\strexpr.h"` and including it in your sources
|
||||
The library can be used partially, just by taking the file `"include/simstr/strexpr.h"` and including it in your sources
|
||||
```cpp
|
||||
#include "include\simstr\strexpr.h"
|
||||
#include "include/simstr/strexpr.h"
|
||||
```
|
||||
This will only connect string expressions and simplified implementations of `simple_str` and `simple_str_nt`, without UTF and Unicode functions.
|
||||
|
||||
|
|
@ -297,8 +302,8 @@ function(add_simstr)
|
|||
simstr
|
||||
GIT_REPOSITORY https://github.com/orefkov/simstr.git
|
||||
GIT_SHALLOW TRUE
|
||||
GIT_TAG tags/rel1.4.0 # Укажите нужный релиз
|
||||
FIND_PACKAGE_ARGS NAMES simstr 1.4.0
|
||||
GIT_TAG tags/rel1.5.0 # Укажите нужный релиз
|
||||
FIND_PACKAGE_ARGS NAMES simstr 1.5.0
|
||||
)
|
||||
FetchContent_MakeAvailable(simstr)
|
||||
endfunction()
|
||||
|
|
|
|||
17
readme_ru.md
17
readme_ru.md
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
[](https://github.com/orefkov/simstr/actions/workflows/cmake-multi-platform.yml)
|
||||
|
||||
Версия 1.4.0.
|
||||
Версия 1.5.0.
|
||||
|
||||
<span class="obfuscator"><a href="readme.md">On English | По-английски</a></span>
|
||||
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
то подход `simstr` вам также будет понятен.
|
||||
|
||||
## Основные возможности библиотеки
|
||||
При использовании только `#include "simstr\strexpr.h"`:
|
||||
При использовании только `#include "simstr/strexpr.h"`:
|
||||
- Поддержка работы со строками `char`, `char8_t`, `char16_t`, `char32_t`, `wchar_t`.
|
||||
- Мощная и расширяемая система *"Строковых выражений"*.
|
||||
Позволяет эффективно реализовать преобразование и сложение (конкатенацию) строк, строковых литералов, чисел (и возможно других объектов),
|
||||
|
|
@ -66,6 +66,11 @@
|
|||
- Слияние (join) контейнеров строк в единую строку, с заданием разделителей и опций - "пропускать пустые", "разделитель после последней".
|
||||
- Разбиение (split) строк на части по заданному разделителю. Разбиение возможно сразу в контейнер со строками, либо вызовом функтора для
|
||||
каждой подстроки, либо путем итерации с помощью итератора `Splitter`.
|
||||
- Функции модификации стандартных строк строковыми выражениями:
|
||||
- str::append, str::prepend, str::insert, str::change - меняют str::string строковыми выражениями,
|
||||
например `str::append(text, "count = "_ss + count)`.
|
||||
- str::replace - заменяет вхождения искомой подстроки на строку замены или строковое выражение.
|
||||
Если подстрока не найдена, строковое выражение даже не вычисляется.
|
||||
- Парсинг целых чисел с возможностью "тонкой" настройки при компиляции - можно задавать опции проверки переполнения,
|
||||
пропуск пробельных символов, конкретное основание счисления либо автовыбор по префиксам `0x`, `0`, `0b`, `0o`,
|
||||
допустимость знака `+`. Парсинг реализован для всех видов строк и символов.
|
||||
|
|
@ -278,9 +283,9 @@ int split_and_calc_total_sim(ssa numbers, ssa delimiter) {
|
|||
- [Описание применяемой техники "Expression Templates"](https://habr.com/ru/articles/936468/)
|
||||
|
||||
## Использование
|
||||
Библиотеку можно использовать частично, просто взяв файл `"include\simstr\strexpr.h"` и включив в свои исходники
|
||||
Библиотеку можно использовать частично, просто взяв файл `"include/simstr/strexpr.h"` и включив в свои исходники
|
||||
```cpp
|
||||
#include "include\simstr\strexpr.h"
|
||||
#include "include/simstr/strexpr.h"
|
||||
```
|
||||
Это подключит только строковые выражения и упрощённые реализации `simple_str` и `simple_str_nt`, без функций работы с UTF и Unicode.
|
||||
|
||||
|
|
@ -298,8 +303,8 @@ function(add_simstr)
|
|||
simstr
|
||||
GIT_REPOSITORY https://github.com/orefkov/simstr.git
|
||||
GIT_SHALLOW TRUE
|
||||
GIT_TAG tags/rel1.4.0 # Укажите нужный релиз
|
||||
FIND_PACKAGE_ARGS NAMES simstr 1.4.0
|
||||
GIT_TAG tags/rel1.5.0 # Укажите нужный релиз
|
||||
FIND_PACKAGE_ARGS NAMES simstr 1.5.0
|
||||
)
|
||||
FetchContent_MakeAvailable(simstr)
|
||||
endfunction()
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
/*
|
||||
* ver. 1.5.0
|
||||
* (c) Проект "SimStr", Александр Орефков orefkov@gmail.com
|
||||
* ver. 1.0
|
||||
* Реализация строковых функций
|
||||
* (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com
|
||||
* Implementation of string functions
|
||||
*/
|
||||
#include "simstr/simple_unicode.h"
|
||||
#include "simstr/sstring.h"
|
||||
|
|
@ -1466,6 +1468,5 @@ SIMSTR_API std::optional<double> impl_to_double(const K* start, const K* end) {
|
|||
template SIMSTR_API std::optional<double> impl_to_double<u8s>(const u8s* start, const u8s* end);
|
||||
template SIMSTR_API std::optional<double> impl_to_double<u16s>(const u16s* start, const u16s* end);
|
||||
template SIMSTR_API std::optional<double> impl_to_double<u32s>(const u32s* start, const u32s* end);
|
||||
template SIMSTR_API std::optional<double> impl_to_double<uws>(const uws* start, const uws* end);
|
||||
|
||||
} // namespace simstr
|
||||
|
|
|
|||
|
|
@ -1,4 +1,12 @@
|
|||
#include "../include/simstr/strexpr.h"
|
||||
/*
|
||||
* ver. 1.5.0
|
||||
* (c) Проект "SimStr", Александр Орефков orefkov@gmail.com
|
||||
* Тесты simstr
|
||||
* (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com
|
||||
* Test of simstr
|
||||
*/
|
||||
|
||||
#include "../include/simstr/strexpr.h"
|
||||
#include <gtest/gtest.h>
|
||||
#include <list>
|
||||
|
||||
|
|
@ -284,6 +292,14 @@ TEST(StrExpr, StrReplace) {
|
|||
std::u16string src = u"-aaaaaaaaaaaaaaaa--";
|
||||
EXPECT_EQ(str::replace(src, u"a", u"vv"_ss + 10, 5, 3), u"-aaaavv10vv10vv10aaaaaaaaa--");
|
||||
}
|
||||
{
|
||||
std::u32string a = U"<" + e_repl(U"test"sv, U"t", U"a" + e_repl(U"test"s, U"es", U"se")) + U">";
|
||||
EXPECT_EQ(a, U"<atsetesatset>");
|
||||
}
|
||||
{
|
||||
std::string a = u8"<" + e_repl("test"sv, "t", u8"a" + e_repl("test"s, "es", "se")) + ">";
|
||||
EXPECT_EQ(a, "<atsetesatset>");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace simstr::tests
|
||||
|
|
|
|||
|
|
@ -1,4 +1,12 @@
|
|||
#include <simstr/sstring.h>
|
||||
/*
|
||||
* ver. 1.5.0
|
||||
* (c) Проект "SimStr", Александр Орефков orefkov@gmail.com
|
||||
* Тесты simstr
|
||||
* (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com
|
||||
* Test of simstr
|
||||
*/
|
||||
|
||||
#include <simstr/sstring.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace std::literals;
|
||||
|
|
@ -1918,6 +1926,27 @@ TEST(SimStr, StrRepl) {
|
|||
|
||||
a = e_repl("test"_ss, "t", "a"_ss + "1" + 10);
|
||||
EXPECT_EQ(a, "a110esa110");
|
||||
|
||||
a = e_repl("test"_ss, "x", "a"_ss + "1" + 10);
|
||||
EXPECT_EQ(a, "test");
|
||||
|
||||
a = e_repl("test"_ss, "t", eea + "a");
|
||||
EXPECT_EQ(a, "aesa");
|
||||
|
||||
a = e_repl("tesd"_ss, "t", eea + "a");
|
||||
EXPECT_EQ(a, "aesd");
|
||||
|
||||
a = e_repl("tttt"_ss, "t", eea);
|
||||
EXPECT_EQ(a, "");
|
||||
|
||||
a = e_repl("-tttttttttttttttttt-"_ss, "t", eea + "a");
|
||||
EXPECT_EQ(a, "-aaaaaaaaaaaaaaaaaa-");
|
||||
|
||||
a = e_repl("-tttttttttttttttttt-"_ss, "t", eea + "aa");
|
||||
EXPECT_EQ(a, "-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-");
|
||||
|
||||
a = "<" + e_repl("test"sv, "t", "a" + e_repl("test"s, "es", "se")) + ">";
|
||||
EXPECT_EQ(a, "<atsetesatset>");
|
||||
}
|
||||
|
||||
TEST(SimStr, HexEpr) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue