mirror of https://github.com/orefkov/simstr.git
Translate continues.
This commit is contained in:
parent
b76486ff2b
commit
f6a0be3e83
|
|
@ -13,8 +13,10 @@ using results_vector = std::vector<result_info>;
|
||||||
|
|
||||||
bool extract_cpu_info(ssa text, ssa& res) {
|
bool extract_cpu_info(ssa text, ssa& res) {
|
||||||
// Найдём, где начинается "Run on ", потом где за ним начинается "\n---"
|
// Найдём, где начинается "Run on ", потом где за ним начинается "\n---"
|
||||||
|
// Find where "Run on" begins, then where after it "\n---" begins
|
||||||
size_t start = text.find("Run on "), end = text.find("\n---", start);
|
size_t start = text.find("Run on "), end = text.find("\n---", start);
|
||||||
// Если что-то не нашлось - ошибка
|
// Если что-то не нашлось - ошибка
|
||||||
|
// If something was not found - an error
|
||||||
if (start == str::npos || end == str::npos) {
|
if (start == str::npos || end == str::npos) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -34,6 +36,7 @@ struct result_info {
|
||||||
throw std::runtime_error{"Not found cpu info"};
|
throw std::runtime_error{"Not found cpu info"};
|
||||||
}
|
}
|
||||||
// Текущее положение поставим сразу за cpuinfo и откинем завершающие переводы строк
|
// Текущее положение поставим сразу за cpuinfo и откинем завершающие переводы строк
|
||||||
|
// We will put the current position immediately after cpuinfo and discard the final line feeds
|
||||||
current_text_ = current_text_(cpu_info_.end() - current_text_.begin() + 1).trimmed_right("\n");
|
current_text_ = current_text_(cpu_info_.end() - current_text_.begin() + 1).trimmed_right("\n");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -57,14 +60,16 @@ stringa get_file_content(stra filePath) {
|
||||||
std::streamsize size = file.tellg();
|
std::streamsize size = file.tellg();
|
||||||
file.seekg(0, std::ios::beg);
|
file.seekg(0, std::ios::beg);
|
||||||
// Такой тип удобен для передачи потом в stringa
|
// Такой тип удобен для передачи потом в stringa
|
||||||
|
// This type is convenient for later passing to stringa
|
||||||
lstringsa<0> result;
|
lstringsa<0> result;
|
||||||
file.read(result.set_size(size), size);
|
file.read(result.set_size(size), size);
|
||||||
result.replace("\r\n", "\n");
|
result.replace("\r\n", "\n");
|
||||||
return result;
|
return std::move(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
results_vector get_results_infos() {
|
results_vector get_results_infos() {
|
||||||
// Отберём в директории results все файлы с названиями, заканчивающимися на ".txt" и отсортируем их по имени
|
// Отберём в директории results все файлы с названиями, заканчивающимися на ".txt" и отсортируем их по имени
|
||||||
|
// Select all files in the results directory with names ending in ".txt" and sort them by name
|
||||||
const ssa suffix = ".txt", dirForResults = "results/";
|
const ssa suffix = ".txt", dirForResults = "results/";
|
||||||
std::vector<stringa> fileNames;
|
std::vector<stringa> fileNames;
|
||||||
for (const auto& f: std::filesystem::directory_iterator{str_to_path(dirForResults)}) {
|
for (const auto& f: std::filesystem::directory_iterator{str_to_path(dirForResults)}) {
|
||||||
|
|
@ -88,6 +93,7 @@ results_vector get_results_infos() {
|
||||||
for (const auto& f : fileNames) {
|
for (const auto& f : fileNames) {
|
||||||
ssa fileName = f;
|
ssa fileName = f;
|
||||||
// В начале имени файла может идти число и дефис, для сортировки, уберём их
|
// В начале имени файла может идти число и дефис, для сортировки, уберём их
|
||||||
|
// At the beginning of the file name there can be a number and a hyphen, for sorting, remove them
|
||||||
if (auto delimeter = fileName.find('-'); delimeter != str::npos && delimeter > 0) {
|
if (auto delimeter = fileName.find('-'); delimeter != str::npos && delimeter > 0) {
|
||||||
if (std::get<1>(fileName(0, delimeter).to_int<unsigned, false, 10, false, false>()) == IntConvertResult::Success) {
|
if (std::get<1>(fileName(0, delimeter).to_int<unsigned, false, 10, false, false>()) == IntConvertResult::Success) {
|
||||||
fileName.remove_prefix(delimeter + 1);
|
fileName.remove_prefix(delimeter + 1);
|
||||||
|
|
@ -188,6 +194,7 @@ ssa extract_source_for_benchmark(ssa benchName, ssa sourceText) {
|
||||||
auto [it, not_exist] = textes.try_emplace(benchName);
|
auto [it, not_exist] = textes.try_emplace(benchName);
|
||||||
if (not_exist) {
|
if (not_exist) {
|
||||||
// Ищем имя функции для этого бенчмарка
|
// Ищем имя функции для этого бенчмарка
|
||||||
|
// Looking for the name of the function for this benchmark
|
||||||
size_t start = sourceText.find(lstringa<128>{"->Name(\"" + e_repl(benchName, "\"", "\\\"") + "\")"});
|
size_t start = sourceText.find(lstringa<128>{"->Name(\"" + e_repl(benchName, "\"", "\\\"") + "\")"});
|
||||||
if (start == str::npos) {
|
if (start == str::npos) {
|
||||||
std::cerr << "Can not found benchmark function name for " << benchName << std::endl;
|
std::cerr << "Can not found benchmark function name for " << benchName << std::endl;
|
||||||
|
|
@ -204,6 +211,7 @@ ssa extract_source_for_benchmark(ssa benchName, ssa sourceText) {
|
||||||
auto [func_it, not_exist] = textes.try_emplace(funcName);
|
auto [func_it, not_exist] = textes.try_emplace(funcName);
|
||||||
if (not_exist) {
|
if (not_exist) {
|
||||||
// Теперь ищем саму эту функцию
|
// Теперь ищем саму эту функцию
|
||||||
|
// Now we look for this function itself
|
||||||
start = sourceText.find(lstringa<128>{funcName + "(benchmark::State"});
|
start = sourceText.find(lstringa<128>{funcName + "(benchmark::State"});
|
||||||
if (start == str::npos) {
|
if (start == str::npos) {
|
||||||
std::cerr << "Can not found source function " << funcName << " for benchmark " << benchName << std::endl;
|
std::cerr << "Can not found source function " << funcName << " for benchmark " << benchName << std::endl;
|
||||||
|
|
@ -218,6 +226,7 @@ ssa extract_source_for_benchmark(ssa benchName, ssa sourceText) {
|
||||||
}
|
}
|
||||||
size_t end = -1;
|
size_t end = -1;
|
||||||
// Проверим, возможно там есть переход на другую функцию через //>
|
// Проверим, возможно там есть переход на другую функцию через //>
|
||||||
|
// Let's check, maybe there is a transition to another function via //>
|
||||||
ssa prevLine = sourceText.from_to(sourceText.find_last('\n', start - 1) + 1, start);
|
ssa prevLine = sourceText.from_to(sourceText.find_last('\n', start - 1) + 1, start);
|
||||||
if (prevLine.starts_with("//> ")) {
|
if (prevLine.starts_with("//> ")) {
|
||||||
prevLine.remove_prefix(4);
|
prevLine.remove_prefix(4);
|
||||||
|
|
@ -262,6 +271,7 @@ void write_benchmarks(out_t& out, const results_vector& results, ssa sourceText,
|
||||||
auto source = extract_source_for_benchmark(benchName, sourceText);
|
auto source = extract_source_for_benchmark(benchName, sourceText);
|
||||||
auto comment = extract_comment(commentsText, benchName);
|
auto comment = extract_comment(commentsText, benchName);
|
||||||
// Нужно вывести название бенча и коммент
|
// Нужно вывести название бенча и коммент
|
||||||
|
// Need to display title and comment
|
||||||
out += "\n<tr><td class=\"benchmarkname\"><span class=\"tooltip\">" +
|
out += "\n<tr><td class=\"benchmarkname\"><span class=\"tooltip\">" +
|
||||||
repl_html_symbols(benchName) +
|
repl_html_symbols(benchName) +
|
||||||
"<span class=\"tooltiptext code\">" +
|
"<span class=\"tooltiptext code\">" +
|
||||||
|
|
@ -296,11 +306,13 @@ void write_benchmarks(out_t& out, const results_vector& results, ssa sourceText,
|
||||||
continue;
|
continue;
|
||||||
} else if (line.starts_with("--") && !line.ends_with("---")) {
|
} else if (line.starts_with("--") && !line.ends_with("---")) {
|
||||||
// Начинается новый набор бенчмарков
|
// Начинается новый набор бенчмарков
|
||||||
|
// Starts a new set of benchmarks
|
||||||
if (needFooter) {
|
if (needFooter) {
|
||||||
write_benchset_footer(out, script_text);
|
write_benchset_footer(out, script_text);
|
||||||
}
|
}
|
||||||
benchName = extract_name_result(line, result);
|
benchName = extract_name_result(line, result);
|
||||||
// Из названия набора надо удалить начальные и конечные ---
|
// Из названия набора надо удалить начальные и конечные ---
|
||||||
|
// From the name of the set we need to remove the beginning and end ---
|
||||||
benchName = benchName.from_to(benchName.find(' ') + 1, benchName.find_last(' ')).trimmed();
|
benchName = benchName.from_to(benchName.find(' ') + 1, benchName.find_last(' ')).trimmed();
|
||||||
write_benchset_header(out, results, benchName, ++benchSetId);
|
write_benchset_header(out, results, benchName, ++benchSetId);
|
||||||
needFooter = true;
|
needFooter = true;
|
||||||
|
|
@ -308,6 +320,7 @@ void write_benchmarks(out_t& out, const results_vector& results, ssa sourceText,
|
||||||
script_text = "bench_sets['" + e_repl(benchName.to_str(), "'", "\\'") + "'] = {id:'bs" + benchSetId +"', tests:[";
|
script_text = "bench_sets['" + e_repl(benchName.to_str(), "'", "\\'") + "'] = {id:'bs" + benchSetId +"', tests:[";
|
||||||
}
|
}
|
||||||
// Эти строки надо пропустить во всех файлах
|
// Эти строки надо пропустить во всех файлах
|
||||||
|
// These lines must be skipped in all files
|
||||||
for (unsigned idx = 1; idx < results.size(); idx++) {
|
for (unsigned idx = 1; idx < results.size(); idx++) {
|
||||||
if (splitters[idx].is_done()) {
|
if (splitters[idx].is_done()) {
|
||||||
std::cerr << "Not expected end of file for " << results[idx].platform_ << std::endl;
|
std::cerr << "Not expected end of file for " << results[idx].platform_ << std::endl;
|
||||||
|
|
|
||||||
|
|
@ -4618,8 +4618,8 @@ struct expr_num {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор конкатенации для строкового выражения и целого числа.
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @brief Оператор конкатенации для строкового выражения и целого числа.
|
||||||
* @param a - строковое выражение
|
* @param a - строковое выражение
|
||||||
* @param s - число
|
* @param s - число
|
||||||
* @details Число конвертируется в десятичное строковое представление.
|
* @details Число конвертируется в десятичное строковое представление.
|
||||||
|
|
@ -4630,8 +4630,8 @@ inline constexpr auto operator + (const A& a, T s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор конкатенации для целого числа и строкового выражения.
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @brief Оператор конкатенации для целого числа и строкового выражения.
|
||||||
* @param s - число
|
* @param s - число
|
||||||
* @param a - строковое выражение
|
* @param a - строковое выражение
|
||||||
* @details Число конвертируется в десятичное строковое представление.
|
* @details Число конвертируется в десятичное строковое представление.
|
||||||
|
|
@ -4642,8 +4642,8 @@ inline constexpr auto operator + (T s, const A& a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Преобразование целого числа в строковое выражение
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @brief Преобразование целого числа в строковое выражение
|
||||||
* @tparam K - тип символов
|
* @tparam K - тип символов
|
||||||
* @tparam T - тип числа, выводится из аргумента
|
* @tparam T - тип числа, выводится из аргумента
|
||||||
* @param t - число
|
* @param t - число
|
||||||
|
|
@ -4690,8 +4690,8 @@ struct expr_real {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор конкатенации для строкового выражения и вещественного числа (`float`, `double`).
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @brief Оператор конкатенации для строкового выражения и вещественного числа (`float`, `double`).
|
||||||
* @param a - строковое выражение
|
* @param a - строковое выражение
|
||||||
* @param s - число
|
* @param s - число
|
||||||
* @details Число конвертируется в строковое представление через sprintf("%.16g").
|
* @details Число конвертируется в строковое представление через sprintf("%.16g").
|
||||||
|
|
@ -4703,8 +4703,8 @@ inline constexpr auto operator+(const A& a, R s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор конкатенации для вещественного числа (`float`, `double`) и строкового выражения.
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @brief Оператор конкатенации для вещественного числа (`float`, `double`) и строкового выражения.
|
||||||
* @param s - число
|
* @param s - число
|
||||||
* @param a - строковое выражение
|
* @param a - строковое выражение
|
||||||
* @details Число конвертируется в строковое представление через `sprintf("%.16g")`.
|
* @details Число конвертируется в строковое представление через `sprintf("%.16g")`.
|
||||||
|
|
@ -4716,8 +4716,8 @@ inline constexpr auto operator+(R s, const A& a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Преобразование `double` числа в строковое выражение
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @brief Преобразование `double` числа в строковое выражение
|
||||||
* @param t - число
|
* @param t - число
|
||||||
* @details Возвращает строковое выражение, которое генерирует десятичное представление заданного числа
|
* @details Возвращает строковое выражение, которое генерирует десятичное представление заданного числа
|
||||||
* с помощью `sprintf("%.16g")`. Может использоваться, когда надо конкатенировть число и строковый литерал
|
* с помощью `sprintf("%.16g")`. Может использоваться, когда надо конкатенировть число и строковый литерал
|
||||||
|
|
@ -4780,8 +4780,8 @@ struct expr_join {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Получить строковое выражение, конкатенирующее строки в контейнере в одну строку с заданным разделителем
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @brief Получить строковое выражение, конкатенирующее строки в контейнере в одну строку с заданным разделителем
|
||||||
* @tparam tail - добавлять ли разделитель после последней строки
|
* @tparam tail - добавлять ли разделитель после последней строки
|
||||||
* @tparam skip_empty - пропускать пустые строки без добавления разделителя
|
* @tparam skip_empty - пропускать пустые строки без добавления разделителя
|
||||||
* @param s - контейнер со строками, должен поддерживать `range for`.
|
* @param s - контейнер со строками, должен поддерживать `range for`.
|
||||||
|
|
@ -4863,8 +4863,8 @@ struct expr_replaces {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Получить строковое выражение, генерирующее строку с заменой всех вхождений заданной подстроки
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @brief Получить строковое выражение, генерирующее строку с заменой всех вхождений заданной подстроки
|
||||||
* @tparam K - тип символа, выводится из первого аргумента
|
* @tparam K - тип символа, выводится из первого аргумента
|
||||||
* @param w - начальная строка
|
* @param w - начальная строка
|
||||||
* @param p - строковый литерал, искомая подстрока
|
* @param p - строковый литерал, искомая подстрока
|
||||||
|
|
@ -4877,8 +4877,8 @@ inline constexpr auto e_repl(simple_str<K> w, T&& p, X&& r) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Строковое выражение, генерирующее строку с заменой всех вхождений заданной подстроки.
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @brief Строковое выражение, генерирующее строку с заменой всех вхождений заданной подстроки.
|
||||||
* @tparam K - тип строкиs
|
* @tparam K - тип строкиs
|
||||||
* @details `e_repl` позволяет заменять только с использование строковых литералов.
|
* @details `e_repl` позволяет заменять только с использование строковых литералов.
|
||||||
* В случае, когда искомая подстрока или строка замены не известны при компиляции, и задаются в runtime,
|
* В случае, когда искомая подстрока или строка замены не известны при компиляции, и задаются в runtime,
|
||||||
|
|
@ -4972,8 +4972,8 @@ template<>
|
||||||
struct replace_search_result_store<true> : std::vector<std::pair<size_t, size_t>> {};
|
struct replace_search_result_store<true> : std::vector<std::pair<size_t, size_t>> {};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Тип для строкового выражения, генерирующее строку, в которой заданные символы заменяются на заданные строки.
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @brief Тип для строкового выражения, генерирующее строку, в которой заданные символы заменяются на заданные строки.
|
||||||
* @tparam K - тип символа
|
* @tparam K - тип символа
|
||||||
* @tparam UseVectorForReplace - использовать вектор для запоминания результатов поиска вхождений символов
|
* @tparam UseVectorForReplace - использовать вектор для запоминания результатов поиска вхождений символов
|
||||||
* @details Этот тип применяется, когда состав символов или соответствующих им замен не известен в compile time,
|
* @details Этот тип применяется, когда состав символов или соответствующих им замен не известен в compile time,
|
||||||
|
|
@ -5359,9 +5359,9 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
* @ingroup StrExprs
|
||||||
* @brief Возвращает строковое выражение, генерирующее строку, в которой заданные символы
|
* @brief Возвращает строковое выражение, генерирующее строку, в которой заданные символы
|
||||||
* заменены на заданные подстроки.
|
* заменены на заданные подстроки.
|
||||||
* @ingroup StrExprs
|
|
||||||
* @tparam UseVector - использовать вектор для сохранения результатов поиска символов.
|
* @tparam UseVector - использовать вектор для сохранения результатов поиска символов.
|
||||||
* Более подробно описано в `expr_replace_symbols`.
|
* Более подробно описано в `expr_replace_symbols`.
|
||||||
* @param src - исходная строка
|
* @param src - исходная строка
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
/*
|
/*
|
||||||
|
* ver. 1.2.4
|
||||||
* (c) Проект "SimStr", Александр Орефков orefkov@gmail.com
|
* (c) Проект "SimStr", Александр Орефков orefkov@gmail.com
|
||||||
* ver. 1.0
|
|
||||||
* База для строковых конкатенаций через выражения времени компиляции
|
* База для строковых конкатенаций через выражения времени компиляции
|
||||||
|
* (c) Project "SimStr", Alexander Orefkov orefkov@gmail.com
|
||||||
|
* Base for string concatenations via compile-time expressions
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
@ -18,6 +20,7 @@
|
||||||
namespace simstr {
|
namespace simstr {
|
||||||
|
|
||||||
// Выводим типы для 16 и 32 битных символов в зависимости от размера wchar_t
|
// Выводим типы для 16 и 32 битных символов в зависимости от размера wchar_t
|
||||||
|
// Infer types for 16 and 32 bit characters depending on the size of wchar_t
|
||||||
inline constexpr bool wchar_is_u16 = sizeof(wchar_t) == 2;
|
inline constexpr bool wchar_is_u16 = sizeof(wchar_t) == 2;
|
||||||
|
|
||||||
using wchar_type = std::conditional<wchar_is_u16, char16_t, char32_t>::type;
|
using wchar_type = std::conditional<wchar_is_u16, char16_t, char32_t>::type;
|
||||||
|
|
@ -92,10 +95,33 @@ void func(T&& lit);
|
||||||
|
|
||||||
Тогда компилятор будет подставлять для T точный тип параметра без попыток привести тип к другому типу,
|
Тогда компилятор будет подставлять для T точный тип параметра без попыток привести тип к другому типу,
|
||||||
и выражение с параметром char[100] - не скомпилируется.
|
и выражение с параметром char[100] - не скомпилируется.
|
||||||
|
|
||||||
|
Helper templates for defining string literals.
|
||||||
|
They are used to limit types in function parameters strictly as `const K(&)[N]`
|
||||||
|
If we write
|
||||||
|
template<size_t N>
|
||||||
|
void func(const char(&lit)[N]);
|
||||||
|
then it will be possible to pass a non-constant buffer to such a function, which may cause an error:
|
||||||
|
|
||||||
|
// Allocate space for symbols
|
||||||
|
char buf[100];
|
||||||
|
// Somehow the buffer was filled, say, to half.
|
||||||
|
|
||||||
|
stringa text = buf;
|
||||||
|
Here the compiler will convert buf from type char[100] to type const char[100] and call the constructor
|
||||||
|
for a string literal, text will simply contain a pointer to buf and length 100.
|
||||||
|
|
||||||
|
Therefore, we declare such parameters as
|
||||||
|
template<typename T, typename K = typename const_lit<T>::symb_type, size_t N = const_lit<T>::Count>
|
||||||
|
void func(T&& lit);
|
||||||
|
|
||||||
|
Then the compiler will substitute for T the exact type of the parameter without attempting to cast the type to another type,
|
||||||
|
and an expression with the char[100] parameter will not compile.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<typename T> struct const_lit; // sfinae отработает, так как не найдёт определения
|
template<typename T> struct const_lit; // sfinae отработает, так как не найдёт определения | sfinae will work because it won't find a definition
|
||||||
// Для правильных типов параметров есть определение, в виде специализации шаблона
|
// Для правильных типов параметров есть определение, в виде специализации шаблона
|
||||||
|
// There is a definition for the correct parameter types, in the form of a template specialization
|
||||||
template<typename T, size_t N>
|
template<typename T, size_t N>
|
||||||
requires(is_one_of_char_v<T>)
|
requires(is_one_of_char_v<T>)
|
||||||
struct const_lit<const T(&)[N]> {
|
struct const_lit<const T(&)[N]> {
|
||||||
|
|
@ -104,6 +130,7 @@ struct const_lit<const T(&)[N]> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Тут ещё дополнительно ограничиваем тип литерала
|
// Тут ещё дополнительно ограничиваем тип литерала
|
||||||
|
// Here we further restrict the type of the literal
|
||||||
template<typename K, typename T> struct const_lit_for;
|
template<typename K, typename T> struct const_lit_for;
|
||||||
|
|
||||||
template<typename K, size_t N>
|
template<typename K, size_t N>
|
||||||
|
|
@ -174,9 +201,9 @@ concept StrType = requires(const A& a) {
|
||||||
} && std::is_same_v<typename std::remove_cvref_t<A>::symb_type, K>;
|
} && std::is_same_v<typename std::remove_cvref_t<A>::symb_type, K>;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Строковые выражения
|
|
||||||
* @defgroup StrExprs Строковые выражения
|
* @defgroup StrExprs Строковые выражения
|
||||||
* @details Все типы владеющих строк могут инициализироваться с помощью "строковых выражений"
|
* @ru @brief Строковые выражения
|
||||||
|
* @ru @details Все типы владеющих строк могут инициализироваться с помощью "строковых выражений"
|
||||||
* (по сути это вариант https://en.wikipedia.org/wiki/Expression_templates для строк).
|
* (по сути это вариант https://en.wikipedia.org/wiki/Expression_templates для строк).
|
||||||
* Строковое выражение - это объект произвольного типа, у которого имеются методы:
|
* Строковое выражение - это объект произвольного типа, у которого имеются методы:
|
||||||
* - `size_t length() const`: выдает длину строки
|
* - `size_t length() const`: выдает длину строки
|
||||||
|
|
@ -203,20 +230,20 @@ concept StrType = requires(const A& a) {
|
||||||
* stringa text = header + ", count = " + count + ", done";
|
* stringa text = header + ", count = " + count + ", done";
|
||||||
* ```
|
* ```
|
||||||
* Существует несколько типов строковых выражений "из коробки", для выполнения различных операций со строками
|
* Существует несколько типов строковых выражений "из коробки", для выполнения различных операций со строками
|
||||||
* - `expr_spaces<ТипСимвола, КоличествоСимволов, Символ>{}`: выдает строку длиной КоличествоСимволов,
|
* - `expr_spaces< ТипСимвола, КоличествоСимволов, Символ>{}`: выдает строку длиной КоличествоСимволов,
|
||||||
* заполненную заданным символом. Количество символов и символ - константы времени компиляции.
|
* заполненную заданным символом. Количество символов и символ - константы времени компиляции.
|
||||||
* Для некоторых случаев есть сокращенная запись:
|
* Для некоторых случаев есть сокращенная запись:
|
||||||
* - `e_spca<КоличествоСимволов>()`: строка char пробелов
|
* - `e_spca< КоличествоСимволов>()`: строка char пробелов
|
||||||
* - `e_spcw<КоличествоСимволов>()`: строка w_char пробелов
|
* - `e_spcw< КоличествоСимволов>()`: строка w_char пробелов
|
||||||
* - `expr_pad<ТипСимвола>{КоличествоСимволов, Символ}`: выдает строку длинной КоличествоСимволов,
|
* - `expr_pad< ТипСимвола>{КоличествоСимволов, Символ}`: выдает строку длинной КоличествоСимволов,
|
||||||
* заполненную заданным символом. Количество символов и символ могут задаваться в рантайме.
|
* заполненную заданным символом. Количество символов и символ могут задаваться в рантайме.
|
||||||
* Сокращенная запись: `e_c(КоличествоСимволов, Символ)`
|
* Сокращенная запись: `e_c (КоличествоСимволов, Символ)`
|
||||||
* - `e_choice(bool Condition, StrExpr1, StrExpr2)`: если Condition == true, результат будет равен StrExpr1, иначе StrExpr2
|
* - `e_choice (bool Condition, StrExpr1, StrExpr2)`: если Condition == true, результат будет равен StrExpr1, иначе StrExpr2
|
||||||
* - `e_num<ТипСимвола>(ЦелоеЧисло)`: конвертирует число в десятичное представление. Редко используется, так как
|
* - `e_num< ТипСимвола>(ЦелоеЧисло)`: конвертирует число в десятичное представление. Редко используется, так как
|
||||||
* для строковых выражений и чисел переопределен оператор "+", и число можно просто написать как text + number;
|
* для строковых выражений и чисел переопределен оператор "+", и число можно просто написать как text + number;
|
||||||
* - `e_real<ТипСимвола>(ВещественноеЧисло)`: конвертирует число в десятичное представление. Редко используется, так как
|
* - `e_real< ТипСимвола>(ВещественноеЧисло)`: конвертирует число в десятичное представление. Редко используется, так как
|
||||||
* для строковых выражений и чисел переопределен оператор "+", и число можно просто написать как `text + number`;
|
* для строковых выражений и чисел переопределен оператор "+", и число можно просто написать как `text + number`;
|
||||||
* - `e_join<bool ПослеПоследнего = false, bool ПропускатьПустые = false>(контейнер, "Разделитель")`: конкатенирует все строки
|
* - `e_join< bool ПослеПоследнего = false, bool ПропускатьПустые = false>(контейнер, "Разделитель")`: конкатенирует все строки
|
||||||
* в контейнере, используя разделитель.
|
* в контейнере, используя разделитель.
|
||||||
* Если `ПослеПоследнего == true`, то разделитель добавляется и после последнего элемента контейнера, иначе только
|
* Если `ПослеПоследнего == true`, то разделитель добавляется и после последнего элемента контейнера, иначе только
|
||||||
* между элементами.
|
* между элементами.
|
||||||
|
|
@ -224,16 +251,70 @@ concept StrType = requires(const A& a) {
|
||||||
* тоже вставляется разделитель
|
* тоже вставляется разделитель
|
||||||
* - `e_repl(ИсходнаяСтрока, "Искать", "Заменять")`: заменяет в исходной строке вхождения "Искать" на "Заменять".
|
* - `e_repl(ИсходнаяСтрока, "Искать", "Заменять")`: заменяет в исходной строке вхождения "Искать" на "Заменять".
|
||||||
* Шаблоны поиска и замены - строковые литералы времени компиляции.
|
* Шаблоны поиска и замены - строковые литералы времени компиляции.
|
||||||
* - `expr_replaced<ТипСимвола>{ИсходнаяСтрока, Искать, Заменять}`: заменяет в исходной строке вхождения Искать на Заменять.
|
* - `expr_replaced< ТипСимвола>{ИсходнаяСтрока, Искать, Заменять}`: заменяет в исходной строке вхождения Искать на Заменять.
|
||||||
* Шаблоны поиска и замены - могут быть любыми строковыми объектами в рантайме.
|
* Шаблоны поиска и замены - могут быть любыми строковыми объектами в рантайме.
|
||||||
*
|
|
||||||
* и т.д. и т.п.
|
* и т.д. и т.п.
|
||||||
|
*
|
||||||
|
* @en @brief Строковые выражения
|
||||||
|
* @en @detailsAll owning string types can be initialized using "string expressions"
|
||||||
|
* (essentially a variant of https://en.wikipedia.org/wiki/Expression_templates for strings).
|
||||||
|
* A string expression is an object of an arbitrary type that has methods:
|
||||||
|
* - `size_t length() const`: returns the length of the string
|
||||||
|
* - `K* place(K*) const`: copy the characters of the string to the intended buffer and return a pointer behind the last character
|
||||||
|
* - `typename symb_type`: shows what type of symbols it works with.
|
||||||
|
*
|
||||||
|
* During initialization, a string object asks the string expression for its size, allocates the necessary memory,
|
||||||
|
* and passes the memory to a string expression that places the characters in the allocated buffer.
|
||||||
|
*
|
||||||
|
* All library string objects are themselves string expressions that simply copy the original string.
|
||||||
|
* Basically, string expressions are used to concatenate or convert strings.
|
||||||
|
*
|
||||||
|
* For all string expressions, @ref op_plus_str_expr "operator +" is defined, which creates a new string expression from two operands
|
||||||
|
* simstr::strexprjoin, which combines two string expressions, and which in the `length` method returns the sum of the `length` original operands,
|
||||||
|
* and in the `place` method - places first the first operand, then the second, into the result buffer.
|
||||||
|
* And since this operator itself returns a string expression, you can again apply `operator +` to it, forming a chain of several
|
||||||
|
* string expressions, and eventually “materialize” the last resulting object, which will first calculate the size of the entire shared memory
|
||||||
|
* for the final result, and then will place the nested subexpressions into a single buffer.
|
||||||
|
*
|
||||||
|
* Also `operator +` is defined for string expressions and string literals, string expressions and numbers
|
||||||
|
* (numbers are converted to decimal representation), and you can also add the desired types of string expressions yourself.
|
||||||
|
* Example:
|
||||||
|
* ```cpp
|
||||||
|
* stringa text = header + ", count = " + count + ", done";
|
||||||
|
* ```
|
||||||
|
* There are several types of string expressions out of the box to perform various operations on strings
|
||||||
|
* - `expr_spaces< Character Type, Number of Characters, Symbol>{}`: returns a string of length Number of Characters,
|
||||||
|
* filled with the specified character. The number of characters and character are compile-time constants.
|
||||||
|
* For some cases there is a shorthand notation:
|
||||||
|
* - `e_spca< Number of Characters>()`: char string of spaces
|
||||||
|
* - `e_spcw< Number of Characters>()`: w_char string of spaces
|
||||||
|
* - `expr_pad< Character Type>{Number of Characters, Symbol}`: produces a string long Number of Characters,
|
||||||
|
* filled with the specified character. The number of characters and the symbol can be set at runtime.
|
||||||
|
* Shorthand: `e_c(Number of Characters, Character)`
|
||||||
|
* - `e_choice(bool Condition, StrExpr1, StrExpr2)`: if Condition == true, the result will be StrExpr1, otherwise StrExpr2
|
||||||
|
* - `e_num< CharacterType>(IntegerNumber)`: Converts a number to decimal notation. Rarely used because
|
||||||
|
* for string expressions and numbers the "+" operator is redefined, and the number can simply be written as text + number;
|
||||||
|
* - `e_real< CharacterType>(RealNumber)`: Converts a number to decimal notation. Rarely used because
|
||||||
|
* for string expressions and numbers the "+" operator is overridden, and the number can simply be written as `text + number`;
|
||||||
|
* - `e_join< bool AfterLast = false, bool SkipEmpty = false>(container, "Separator")`: concatenates all strings
|
||||||
|
* in a container using a separator.
|
||||||
|
* If `AfterLast == true`, then the separator is added after the last element of the container, otherwise only
|
||||||
|
* between elements.
|
||||||
|
* If `Skip Empty == true`, then empty lines do not add a separator, otherwise for each empty line
|
||||||
|
* a separator is also inserted
|
||||||
|
* - `e_repl(SourceString, "Search", "Replace")`: replaces occurrences of "Search" with "Replace" in the source string.
|
||||||
|
* Find and replace patterns are compile-time string literals.
|
||||||
|
* - `expr_replaced< CharacterType>{SourceString, Search, Replace}`: replaces occurrences of Search with Replace in the source string.
|
||||||
|
* Search and replace patterns - can be any string objects at runtime.
|
||||||
|
* etc. etc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Концепт "Строковых выражений"
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @details Это концепт, проверяющий, является ли тип "строковым выражением".
|
* @ru @brief Концепт "Строковых выражений"
|
||||||
|
* @ru @details Это концепт, проверяющий, является ли тип "строковым выражением".
|
||||||
|
* @en @brief Concept of "String Expressions"
|
||||||
|
* @en @details This is a concept that checks whether a type is a "string expression".
|
||||||
*/
|
*/
|
||||||
template<typename A>
|
template<typename A>
|
||||||
concept StrExpr = requires(const A& a) {
|
concept StrExpr = requires(const A& a) {
|
||||||
|
|
@ -243,32 +324,49 @@ concept StrExpr = requires(const A& a) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Концепт строкового выражения заданного типа символов
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @tparam A - проверяемый тип
|
* @ru @brief Концепт строкового выражения заданного типа символов
|
||||||
* @tparam K - проверяемый тип символов
|
* @ru @tparam A - проверяемый тип
|
||||||
* @details Служит для задания ограничения к строковому выражению по типу символов
|
* @ru @tparam K - проверяемый тип символов
|
||||||
|
* @ru @details Служит для задания ограничения к строковому выражению по типу символов
|
||||||
|
* @en @brief The concept of a string expression of a given character type
|
||||||
|
* @en @tparam A - type being checked
|
||||||
|
* @en @tparam K - character type to be checked
|
||||||
|
* @en @details Used to set restrictions on a string expression by character type
|
||||||
*/
|
*/
|
||||||
template<typename A, typename K>
|
template<typename A, typename K>
|
||||||
concept StrExprForType = StrExpr<A> && std::is_same_v<K, typename A::symb_type>;
|
concept StrExprForType = StrExpr<A> && std::is_same_v<K, typename A::symb_type>;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Шаблонные классы для создания строковых выражений из нескольких источников
|
* Шаблонные классы для создания строковых выражений из нескольких источников.
|
||||||
* Благодаря компиляторно-шаблонной "магии" позволяют максимально эффективно
|
* Благодаря компиляторно-шаблонной "магии" позволяют максимально эффективно
|
||||||
* получать результирующую строку - сначала вычисляется длина результирующей строки,
|
* получать результирующую строку - сначала вычисляется длина результирующей строки,
|
||||||
* потом один раз выделяется память для результата, после символы помещаются в
|
* потом один раз выделяется память для результата, после символы помещаются в
|
||||||
* выделенную память.
|
* выделенную память.
|
||||||
* Для конкатенация двух объектов строковых выражений в один
|
* Для конкатенация двух объектов строковых выражений в один
|
||||||
|
|
||||||
|
* Template classes for creating string expressions from multiple sources.
|
||||||
|
* Thanks to compiler-template "magic" they allow you to maximize efficiency
|
||||||
|
* get the resulting string - first the length of the resulting string is calculated,
|
||||||
|
* then memory is allocated once for the result, after which the characters are placed in
|
||||||
|
* allocated memory.
|
||||||
|
* For concatenating two string expression objects into one.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Шаблонный класс для конкатенации двух строковых выражений в одно с помощью `operator +`
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @tparam A - Тип первого операнда
|
* @ru @brief Шаблонный класс для конкатенации двух строковых выражений в одно с помощью `operator +`
|
||||||
* @tparam B - Тип второго операнда
|
* @ru @tparam A - Тип первого операнда
|
||||||
* @details Этот объект запоминает ссылки на два операнда операции сложения.
|
* @ru @tparam B - Тип второго операнда
|
||||||
|
* @ru @details Этот объект запоминает ссылки на два операнда операции сложения.
|
||||||
* Когда у него запрашивают необходимый для результата размер буфера - он выдает сумму длин своих операндов.
|
* Когда у него запрашивают необходимый для результата размер буфера - он выдает сумму длин своих операндов.
|
||||||
* Когда запрашивают размещение символов в буфере - размещает сначала первый операнд, затем второй.
|
* Когда запрашивают размещение символов в буфере - размещает сначала первый операнд, затем второй.
|
||||||
|
* @en @brief Template class for concatenating two string expressions into one using `operator +`
|
||||||
|
* @en @tparam A - Type of first operand
|
||||||
|
* @en @tparam B - Type of second operand
|
||||||
|
* @en @detailsThis object remembers references to the two operands of the addition operation.
|
||||||
|
* When asked for the required buffer size for a result, it gives the sum of the lengths of its operands.
|
||||||
|
* When asked to place characters in a buffer, place the first operand first, then the second.
|
||||||
*/
|
*/
|
||||||
template<StrExpr A, StrExprForType<typename A::symb_type> B>
|
template<StrExpr A, StrExprForType<typename A::symb_type> B>
|
||||||
struct strexprjoin {
|
struct strexprjoin {
|
||||||
|
|
@ -290,17 +388,27 @@ struct strexprjoin {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор сложения двух произвольных строковых выражения для одинакового типа символов
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @anchor op_plus_str_expr
|
* @anchor op_plus_str_expr
|
||||||
* @param a - первое строковое выражение
|
* @ru @brief Оператор сложения двух произвольных строковых выражения для одинакового типа символов.
|
||||||
* @param b - второе строковое выражение
|
* @ru @param a - первое строковое выражение.
|
||||||
* @return strexprjoin<A, B>, строковое выражение, генерирующее объединение переданных выражений
|
* @ru @param b - второе строковое выражение.
|
||||||
* @details Когда складываются два объекта - строковых выражения, один типа `A`, другой типа `B`,
|
* @ru @return strexprjoin<A, B>, строковое выражение, генерирующее объединение переданных выражений.
|
||||||
|
* @ru @details Когда складываются два объекта - строковых выражения, один типа `A`, другой типа `B`,
|
||||||
* мы возвращаем объект типа strexprjoin<A, B>, который содержит ссылки на два этих операнда.
|
* мы возвращаем объект типа strexprjoin<A, B>, который содержит ссылки на два этих операнда.
|
||||||
* А сам объект strexprjoin<A, B> тоже в свою очередь является строковым выражением, и может участвовать
|
* А сам объект strexprjoin<A, B> тоже в свою очередь является строковым выражением, и может участвовать
|
||||||
* в следующих операциях сложения. Таким образом формируется "дерево" из исходных строковых
|
* в следующих операциях сложения. Таким образом формируется "дерево" из исходных строковых
|
||||||
* выражений, которое потом за один вызов "материализуется" в конечный результат.
|
* выражений, которое потом за один вызов "материализуется" в конечный результат.
|
||||||
|
*
|
||||||
|
* @en @brief An addition operator for two arbitrary string expressions of the same character type.
|
||||||
|
* @en @param a - first string expression
|
||||||
|
* @en @param b - second string expression
|
||||||
|
* @en @return strexprjoin<A, B>, a string expression that generates a join of the given expressions.
|
||||||
|
* @en @details When two objects are added - string expressions, one of type `A`, the other of type `B`,
|
||||||
|
* we return an object of type strexprjoin<A, B>, which contains references to these two operands.
|
||||||
|
* And the strexprjoin<A, B> object itself, in turn, is also a string expression, and can participate
|
||||||
|
* in the following addition operations. In this way, a “tree” is formed from the original strings
|
||||||
|
* expressions, which are then “materialized” into the final result in one call.
|
||||||
*/
|
*/
|
||||||
template<StrExpr A, StrExprForType<typename A::symb_type> B>
|
template<StrExpr A, StrExprForType<typename A::symb_type> B>
|
||||||
inline auto operator+(const A& a, const B& b) {
|
inline auto operator+(const A& a, const B& b) {
|
||||||
|
|
@ -308,15 +416,24 @@ inline auto operator+(const A& a, const B& b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Конкатенация ссылки на строковое выражение и значения строкового выражения
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @tparam A - Тип одного строкового выражения
|
* @ru @brief Конкатенация ссылки на строковое выражение и значения строкового выражения.
|
||||||
* @tparam B - Тип другого строкового выражения
|
* @ru @tparam A - Тип одного строкового выражения.
|
||||||
* @tparam last - какое из них первое
|
* @ru @tparam B - Тип другого строкового выражения.
|
||||||
* @details Чтобы иметь возможность складывать строковое выражение с операндами, не являющимися строковым выражением,
|
* @ru @tparam last - какое из них первое.
|
||||||
|
* @ru @details Чтобы иметь возможность складывать строковое выражение с операндами, не являющимися строковым выражением,
|
||||||
* нам нужно иметь возможность вернуть из `operator+` объект, который сохранит ссылку на операнд, являющийся строковым
|
* нам нужно иметь возможность вернуть из `operator+` объект, который сохранит ссылку на операнд, являющийся строковым
|
||||||
* выражением, а для не строкового операнда будет иметь поле со строковым выражением, обрабатывающим второй операнд.
|
* выражением, а для не строкового операнда будет иметь поле со строковым выражением, обрабатывающим второй операнд.
|
||||||
* Можно посмотреть пример в simstr::operator+<StrExpr A, FromIntNumber T>()
|
* Можно посмотреть пример в simstr::operator+<StrExpr A, FromIntNumber T>()
|
||||||
|
*
|
||||||
|
* @en @brief Concatenation of a reference to a string expression and the value of the string expression.
|
||||||
|
* @en @tparam A - Type of a single string expression.
|
||||||
|
* @en @tparam B - Type of another string expression.
|
||||||
|
* @en @tparam last - which one is the first.
|
||||||
|
* @en @details To be able to add a string expression with non-string operands,
|
||||||
|
* we need to be able to return an object from `operator+` that will retain a reference to the operand, which is a string
|
||||||
|
* expression, and for a non-string operand will have a field with a string expression that processes the second operand.
|
||||||
|
* You can see an example in simstr::operator+<StrExpr A, FromIntNumber T>()
|
||||||
*/
|
*/
|
||||||
template<StrExpr A, StrExprForType<typename A::symb_type> B, bool last = true>
|
template<StrExpr A, StrExprForType<typename A::symb_type> B, bool last = true>
|
||||||
struct strexprjoin_c {
|
struct strexprjoin_c {
|
||||||
|
|
@ -350,10 +467,10 @@ template<typename T>
|
||||||
struct is_one_of_type<T, void> : std::false_type {};
|
struct is_one_of_type<T, void> : std::false_type {};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief "Пустое" строковое выражение
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @tparam K - тип символа
|
* @ru @brief "Пустое" строковое выражение.
|
||||||
* @details Простое строковое выражение, генерирующее пустую строку.
|
* @ru @tparam K - тип символа.
|
||||||
|
* @ru @details Простое строковое выражение, генерирующее пустую строку.
|
||||||
* В основном применяется в функции e_choice, когда одна из веток должна вернуть пустую строку.
|
* В основном применяется в функции e_choice, когда одна из веток должна вернуть пустую строку.
|
||||||
* Либо для начала операции сложения строковых выражений, когда другой операнд не является строковым выражением,
|
* Либо для начала операции сложения строковых выражений, когда другой операнд не является строковым выражением,
|
||||||
* но для него есть оператор сложения со строковыми выражениями.
|
* но для него есть оператор сложения со строковыми выражениями.
|
||||||
|
|
@ -363,7 +480,20 @@ struct is_one_of_type<T, void> : std::false_type {};
|
||||||
* - eeu для пустой строки char16_t
|
* - eeu для пустой строки char16_t
|
||||||
* - eeuu для пустой строки char32_t
|
* - eeuu для пустой строки char32_t
|
||||||
*
|
*
|
||||||
* Пример:
|
* @en @brief An "empty" string expression.
|
||||||
|
* @en @tparam K is a symbol.
|
||||||
|
* @en @details A simple string expression that generates an empty string.
|
||||||
|
* Mainly used in the e_choice function when one of the branches should return an empty string.
|
||||||
|
* Either to start the addition operation of string expressions when the other operand is not a string expression,
|
||||||
|
* but there is an addition operator for it with string expressions.
|
||||||
|
* For convenience, constant objects of this type have already been defined for different types of symbols:
|
||||||
|
* - eea for empty char string
|
||||||
|
* - eew for empty string wchar_t
|
||||||
|
* - eeu for empty string char16_t
|
||||||
|
* - eeuu for empty string char32_t
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @ru Пример: @en Example: @~
|
||||||
* ```cpp
|
* ```cpp
|
||||||
* result = shost + e_choice(sserv.is_empty(), eea, ":" + sserv);
|
* result = shost + e_choice(sserv.is_empty(), eea, ":" + sserv);
|
||||||
* ```
|
* ```
|
||||||
|
|
@ -384,23 +514,27 @@ struct empty_expr {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Пустое строковое выражение типа char
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Пустое строковое выражение типа char.
|
||||||
|
* @en @brief Empty string expression of type char.
|
||||||
*/
|
*/
|
||||||
inline constexpr empty_expr<u8s> eea{};
|
inline constexpr empty_expr<u8s> eea{};
|
||||||
/*!
|
/*!
|
||||||
* @brief Пустое строковое выражение типа wchar_t
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Пустое строковое выражение типа wchar_t.
|
||||||
|
* @en @brief Empty string expression of type wchar_t.
|
||||||
*/
|
*/
|
||||||
inline constexpr empty_expr<uws> eew{};
|
inline constexpr empty_expr<uws> eew{};
|
||||||
/*!
|
/*!
|
||||||
* @brief Пустое строковое выражение типа char16_t
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Пустое строковое выражение типа char16_t.
|
||||||
|
* @en @brief Empty string expression of type char16_t.
|
||||||
*/
|
*/
|
||||||
inline constexpr empty_expr<u16s> eeu{};
|
inline constexpr empty_expr<u16s> eeu{};
|
||||||
/*!
|
/*!
|
||||||
* @brief Пустое строковое выражение типа char32_t
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Пустое строковое выражение типа char32_t.
|
||||||
|
* @en @brief Empty string expression of type char32_t.
|
||||||
*/
|
*/
|
||||||
inline constexpr empty_expr<u32s> eeuu{};
|
inline constexpr empty_expr<u32s> eeuu{};
|
||||||
|
|
||||||
|
|
@ -419,10 +553,13 @@ struct expr_char {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор сложения строкового выражения и одного символа
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @return строковое выражение, объединяющее переданное выражение и символ
|
* @ru @brief Оператор сложения строкового выражения и одного символа.
|
||||||
* @details Пример:
|
* @ru @return строковое выражение, объединяющее переданное выражение и символ.
|
||||||
|
* @en @brief Addition operator of a string expression and one character.
|
||||||
|
* @en @return a string expression that combines the passed expression and a character.
|
||||||
|
* @details @ru Пример: @en Example: @~
|
||||||
|
* @~
|
||||||
* ```cpp
|
* ```cpp
|
||||||
* reply = prompt + '>' + result;
|
* reply = prompt + '>' + result;
|
||||||
* ```
|
* ```
|
||||||
|
|
@ -433,10 +570,14 @@ constexpr inline auto operator+(const A& a, K s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Генерирует строку из 1 заданного символа
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @param S - символ
|
* @ru @brief Генерирует строку из 1 заданного символа.
|
||||||
* @return строковое выражение для строки из одного символа
|
* @ru @param s - символ.
|
||||||
|
* @ru @return строковое выражение для строки из одного символа.
|
||||||
|
*
|
||||||
|
* @en @brief Generates a string of 1 given character.
|
||||||
|
* @en @param s - symbol.
|
||||||
|
* @en @return string expression for a single character string.
|
||||||
*/
|
*/
|
||||||
template<typename K>
|
template<typename K>
|
||||||
constexpr inline auto e_char(K s) {
|
constexpr inline auto e_char(K s) {
|
||||||
|
|
@ -458,9 +599,9 @@ struct expr_literal {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Преобразует строковый литерал в строковое выражение.
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @details Строковые литералы сами по себе не являются строковыми выражениями.
|
* @ru @brief Преобразует строковый литерал в строковое выражение.
|
||||||
|
* @ru @details Строковые литералы сами по себе не являются строковыми выражениями.
|
||||||
* Обычно в операциях конкатенации это не вызывает проблем, так как второй операнд уже является строковым выражением,
|
* Обычно в операциях конкатенации это не вызывает проблем, так как второй операнд уже является строковым выражением,
|
||||||
* и для него срабатывает сложение с литералом. Но есть ситуации, когда второй операнд тоже не является
|
* и для него срабатывает сложение с литералом. Но есть ситуации, когда второй операнд тоже не является
|
||||||
* строковым выражением. Например:
|
* строковым выражением. Например:
|
||||||
|
|
@ -483,6 +624,31 @@ struct expr_literal {
|
||||||
* - Преобразовать другой операнд в строковое выражение: `result = "text" + e_num<u8s>(intVar)`.
|
* - Преобразовать другой операнд в строковое выражение: `result = "text" + e_num<u8s>(intVar)`.
|
||||||
*
|
*
|
||||||
* Все эти способы работают и выдают одинаковый результат. Каким пользоваться - дело вкуса.
|
* Все эти способы работают и выдают одинаковый результат. Каким пользоваться - дело вкуса.
|
||||||
|
*
|
||||||
|
* @en @brief Converts a string literal to a string expression.
|
||||||
|
* @en @details String literals are not themselves string expressions.
|
||||||
|
* This usually does not cause problems in concatenation operations, since the second operand is already a string expression,
|
||||||
|
* and addition with a literal works for it. But there are situations when the second operand is not either
|
||||||
|
* string expression. For example:
|
||||||
|
* ```cpp
|
||||||
|
* int intVar = calculate();
|
||||||
|
* ...
|
||||||
|
* res = "text" + intVar;
|
||||||
|
* ...
|
||||||
|
* res = intVar + "text";
|
||||||
|
* ```
|
||||||
|
* In this case, you can convert the literal to a string expression in two ways:
|
||||||
|
* - add _ss: `"text"_ss`, which converts the literal to simple_str_nt: `res = "text"_ss + intVar`
|
||||||
|
* - apply e_t: `e_t("text")`, which converts the literal to expr_literal: `res = e_t("text") + intVar`
|
||||||
|
*
|
||||||
|
* In the second method, the compiler can more aggressively apply optimizations related to what is known at compilation
|
||||||
|
* literal size.
|
||||||
|
*
|
||||||
|
* Although strictly speaking, in these situations you can use other methods:
|
||||||
|
* - Add an operand - an empty string expression: `result = eea + "text" + intVar`, `result = "text" + eea + intVar`
|
||||||
|
* - Convert another operand to a string expression: `result = "text" + e_num<u8s>(intVar)`.
|
||||||
|
*
|
||||||
|
* All these methods work and give the same result. Which one to use is a matter of taste.
|
||||||
*/
|
*/
|
||||||
template<typename T, size_t N = const_lit<T>::Count>
|
template<typename T, size_t N = const_lit<T>::Count>
|
||||||
constexpr inline auto e_t(T&& s) {
|
constexpr inline auto e_t(T&& s) {
|
||||||
|
|
@ -518,9 +684,11 @@ struct expr_literal_join {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор сложения для строкового выражения и строкового литерала такого же типа символов
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @return Строковое выражение, объединяющее операнды
|
* @ru @brief Оператор сложения для строкового выражения и строкового литерала такого же типа символов.
|
||||||
|
* @ru @return Строковое выражение, объединяющее операнды.
|
||||||
|
* @en @brief The addition operator for a string expression and a string literal of the same character type.
|
||||||
|
* @en @return A string expression concatenating the operands.
|
||||||
*/
|
*/
|
||||||
template<StrExpr A, typename K = typename A::symb_type, typename T, size_t N = const_lit_for<K, T>::Count>
|
template<StrExpr A, typename K = typename A::symb_type, typename T, size_t N = const_lit_for<K, T>::Count>
|
||||||
constexpr inline auto operator+(const A& a, T&& s) {
|
constexpr inline auto operator+(const A& a, T&& s) {
|
||||||
|
|
@ -528,9 +696,11 @@ constexpr inline auto operator+(const A& a, T&& s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор сложения для строкового литерала такого же типа символов и строкового выражения
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @return Строковое выражение, объединяющее операнды
|
* @ru @brief Оператор сложения для строкового литерала такого же типа символов и строкового выражения.
|
||||||
|
* @ru @return Строковое выражение, объединяющее операнды.
|
||||||
|
* @en @brief The addition operator for a string literal of the same character type and string expression.
|
||||||
|
* @en @return A string expression concatenating the operands.
|
||||||
*/
|
*/
|
||||||
template<StrExpr A, typename K = typename A::symb_type, typename T, size_t N = const_lit_for<K, T>::Count>
|
template<StrExpr A, typename K = typename A::symb_type, typename T, size_t N = const_lit_for<K, T>::Count>
|
||||||
constexpr inline auto operator+(T&& s, const A& a) {
|
constexpr inline auto operator+(T&& s, const A& a) {
|
||||||
|
|
@ -538,12 +708,17 @@ constexpr inline auto operator+(T&& s, const A& a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Тип строкового выражения, возвращающего N заданных символов.
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @details Количество символов и сам символ константы, т.е. задаются при компиляции.
|
* @ru @brief Тип строкового выражения, возвращающего N заданных символов.
|
||||||
* @tparam K - тип символа
|
* @ru @details Количество символов и сам символ константы, т.е. задаются при компиляции.
|
||||||
* @tparam N - количество символов
|
* @ru @tparam K - тип символа.
|
||||||
* @tparam S - символ, по умолчанию пробел
|
* @ru @tparam N - количество символов.
|
||||||
|
* @ru @tparam S - символ, по умолчанию пробел.
|
||||||
|
* @en @brief A type of string expression that returns N specified characters.
|
||||||
|
* @en @details The number of characters and the constant symbol itself, i.e. are specified during compilation.
|
||||||
|
* @en @tparam K is a symbol.
|
||||||
|
* @en @tparam N - number of characters.
|
||||||
|
* @en @tparam S - character, space by default.
|
||||||
*/
|
*/
|
||||||
template<typename K, size_t N, size_t S = ' '>
|
template<typename K, size_t N, size_t S = ' '>
|
||||||
struct expr_spaces {
|
struct expr_spaces {
|
||||||
|
|
@ -559,11 +734,14 @@ struct expr_spaces {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Генерирует строку из N char пробелов
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @tparam N - Количество пробелов
|
* @ru @brief Генерирует строку из N char пробелов.
|
||||||
* @return строковое выражение для N char пробелов
|
* @ru @tparam N - Количество пробелов.
|
||||||
* @details Пример:
|
* @ru @return строковое выражение для N char пробелов.
|
||||||
|
* @en @brief Generates a string of N char spaces.
|
||||||
|
* @en @tparam N - Number of spaces.
|
||||||
|
* @en @return string expression for N char spaces.
|
||||||
|
* @details @ru Пример: @en Example: @~
|
||||||
* ```cpp
|
* ```cpp
|
||||||
* stringa text = e_spca<10>() + text + e_spca<10>();
|
* stringa text = e_spca<10>() + text + e_spca<10>();
|
||||||
* ```
|
* ```
|
||||||
|
|
@ -574,11 +752,14 @@ constexpr inline auto e_spca() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Генерирует строку из N wchar_t пробелов
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @tparam N - Количество пробелов
|
* @ru @brief Генерирует строку из N wchar_t пробелов.
|
||||||
* @return строковое выражение для N wchar_t пробелов
|
* @ru @tparam N - Количество пробелов.
|
||||||
* @details Пример:
|
* @ru @return строковое выражение для N wchar_t пробелов.
|
||||||
|
* @en @brief Generates a string of N wchar_t spaces.
|
||||||
|
* @en @tparam N - Number of spaces.
|
||||||
|
* @en @return string expression for N wchar_t spaces.
|
||||||
|
* @details @ru Пример: @en Example: @~
|
||||||
* ```cpp
|
* ```cpp
|
||||||
* stringw text = e_spcw<10>() + text + e_spcw<10>();
|
* stringw text = e_spcw<10>() + text + e_spcw<10>();
|
||||||
* ```
|
* ```
|
||||||
|
|
@ -589,11 +770,15 @@ constexpr inline auto e_spcw() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Тип строкового выражения, возвращающего N заданных символов.
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @tparam K - тип символа
|
* @ru @brief Тип строкового выражения, возвращающего N заданных символов.
|
||||||
* @details Количество символов и сам символ переменные, т.е. могут меняться в рантайм.
|
* @ru @tparam K - тип символа.
|
||||||
* Напрямую обычно не используется, создается через e_c()
|
* @ru @details Количество символов и сам символ переменные, т.е. могут меняться в рантайм.
|
||||||
|
* Напрямую обычно не используется, создается через e_c().
|
||||||
|
* @en @brief A type of string expression that returns N specified characters.
|
||||||
|
* @en @tparam K is a symbol.
|
||||||
|
* @en @details The number of characters and the character itself are variable, i.e. can change at runtime.
|
||||||
|
* Usually not used directly, created via e_c().
|
||||||
*/
|
*/
|
||||||
template<typename K>
|
template<typename K>
|
||||||
struct expr_pad {
|
struct expr_pad {
|
||||||
|
|
@ -611,12 +796,17 @@ struct expr_pad {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Генерирует строку из l символов s типа K
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @tparam K - тип символа
|
* @ru @brief Генерирует строку из l символов s типа K.
|
||||||
* @param l - количество символов
|
* @ru @tparam K - тип символа.
|
||||||
* @param s - символ
|
* @ru @param l - количество символов.
|
||||||
* @return строковое выражение, генерирующее строку из l символов k
|
* @ru @param s - символ.
|
||||||
|
* @ru @return строковое выражение, генерирующее строку из l символов k.
|
||||||
|
* @en @brief Generates a string of l characters s of type K.
|
||||||
|
* @en @tparam K is a symbol.
|
||||||
|
* @en @param l - number of characters.
|
||||||
|
* @en @param s - symbol.
|
||||||
|
* @en @return a string expression that generates a string of l characters k.
|
||||||
*/
|
*/
|
||||||
template<typename K>
|
template<typename K>
|
||||||
constexpr inline auto e_c(size_t l, K s) {
|
constexpr inline auto e_c(size_t l, K s) {
|
||||||
|
|
@ -624,12 +814,17 @@ constexpr inline auto e_c(size_t l, K s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Строковое выражение условного выбора
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @tparam A Тип ветки для true
|
* @ru @brief Строковое выражение условного выбора.
|
||||||
* @tparam B Тип ветки для false
|
* @ru @tparam A Тип ветки для true.
|
||||||
* @details Выражение, в зависимости от истинности условия генерирующее либо выражение A, либо выражение B.
|
* @ru @tparam B Тип ветки для false.
|
||||||
* Напрямую тип обычно не используется, создаётся через e_choice()
|
* @ru @details Выражение, в зависимости от истинности условия генерирующее либо выражение A, либо выражение B.
|
||||||
|
* Напрямую тип обычно не используется, создаётся через e_choice().
|
||||||
|
* @en @brief Conditional selection string expression.
|
||||||
|
* @en @tparam A Branch type for true.
|
||||||
|
* @en @tparam B Branch type for false.
|
||||||
|
* @en @details An expression that, depending on the truth of the condition, generates either expression A or expression B.
|
||||||
|
* The type is usually not used directly; it is created via e_choice().
|
||||||
*/
|
*/
|
||||||
template<StrExpr A, StrExprForType<typename A::symb_type> B>
|
template<StrExpr A, StrExprForType<typename A::symb_type> B>
|
||||||
struct expr_choice {
|
struct expr_choice {
|
||||||
|
|
@ -648,11 +843,15 @@ struct expr_choice {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Строковое выражение условного выбора
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @tparam A Тип ветки для true
|
* @ru @brief Строковое выражение условного выбора.
|
||||||
* @details Выражение, в зависимости от истинности условия генерирующее либо выражение A, либо пустую строку.
|
* @ru @tparam A Тип ветки для true.
|
||||||
* Напрямую тип обычно не используется, создаётся через e_if()
|
* @ru @details Выражение, в зависимости от истинности условия генерирующее либо выражение A, либо пустую строку.
|
||||||
|
* Напрямую тип обычно не используется, создаётся через e_if().
|
||||||
|
* @en @brief Conditional selection string expression.
|
||||||
|
* @en @tparam A Branch type for true.
|
||||||
|
* @en @details An expression that, depending on the truth of the condition, generates either expression A or an empty string.
|
||||||
|
* Title type usually not used, create through e_if().
|
||||||
*/
|
*/
|
||||||
template<StrExpr A>
|
template<StrExpr A>
|
||||||
struct expr_if {
|
struct expr_if {
|
||||||
|
|
@ -670,11 +869,11 @@ struct expr_if {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Строковое выражение условного выбора
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @tparam A Тип ветки для true
|
* @ru @brief Строковое выражение условного выбора.
|
||||||
* @details Выражение, в зависимости от истинности условия генерирующее либо выражение A, либо строку из строкового литерала.
|
* @ru @tparam A Тип ветки для true.
|
||||||
* Напрямую тип обычно не используется, создаётся через e_choice()
|
* @ru @details Выражение, в зависимости от истинности условия генерирующее либо выражение A, либо строку из строкового литерала.
|
||||||
|
* Напрямую тип обычно не используется, создаётся через e_choice().
|
||||||
*
|
*
|
||||||
* Так как строковые литералы не являются строковыми выражениями, то использовать их в виде одиночного выражения в частях
|
* Так как строковые литералы не являются строковыми выражениями, то использовать их в виде одиночного выражения в частях
|
||||||
* e_choice или e_if требовало бы их обрамления какими-либо конструкциями, преобразующими их в строковое выражение.
|
* e_choice или e_if требовало бы их обрамления какими-либо конструкциями, преобразующими их в строковое выражение.
|
||||||
|
|
@ -693,6 +892,27 @@ struct expr_if {
|
||||||
* e_choice(condition, "false", "true");
|
* e_choice(condition, "false", "true");
|
||||||
* e_if(!condition, "empty");
|
* e_if(!condition, "empty");
|
||||||
* ```
|
* ```
|
||||||
|
* @en @brief Conditional selection string expression.
|
||||||
|
* @en @tparam A Branch type for true.
|
||||||
|
* @en @details An expression that, depending on the truth of the condition, generates either expression A or a string from a string literal.
|
||||||
|
* The type is usually not used directly; it is created via e_choice().
|
||||||
|
*
|
||||||
|
* Since string literals are not string expressions, use them as a single expression in parts
|
||||||
|
* e_choice or e_if would require them to be surrounded by some constructs that convert them to a string expression.
|
||||||
|
* You would have to write something like this:
|
||||||
|
* ```cpp
|
||||||
|
* e_choice(condition, text, e_t("empty"));
|
||||||
|
* e_choice(condition, text, eea + "empty");
|
||||||
|
* e_choice(condition, text, "empty"_ss);
|
||||||
|
* e_if(!condition, "empty"_ss);
|
||||||
|
* ```
|
||||||
|
* This, on the one hand, clutters up the code, on the other, makes it less optimal.
|
||||||
|
* These overloads use expr_choice_one_lit and expr_choice_two_lit, allowing you to write like this:
|
||||||
|
* ```cpp
|
||||||
|
* e_choice(condition, text, "empty");
|
||||||
|
* e_choice(condition, "false", "true");
|
||||||
|
* e_if(!condition, "empty");
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
template<StrExpr A, size_t N, bool Compare>
|
template<StrExpr A, size_t N, bool Compare>
|
||||||
struct expr_choice_one_lit {
|
struct expr_choice_one_lit {
|
||||||
|
|
@ -716,10 +936,10 @@ struct expr_choice_one_lit {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Строковое выражение условного выбора
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @details Выражение, в зависимости от истинности условия генерирующее либо один строковый литерал, либо другой.
|
* @ru @brief Строковое выражение условного выбора.
|
||||||
* Напрямую тип обычно не используется, создаётся через e_choice()
|
* @ru @details Выражение, в зависимости от истинности условия генерирующее либо один строковый литерал, либо другой.
|
||||||
|
* Напрямую тип обычно не используется, создаётся через e_choice().
|
||||||
*
|
*
|
||||||
* Так как строковые литералы не являются строковыми выражениями, то использовать их в виде одиночного выражения в частях
|
* Так как строковые литералы не являются строковыми выражениями, то использовать их в виде одиночного выражения в частях
|
||||||
* e_choice или e_if требовало бы их обрамления какими-либо конструкциями, преобразующими их в строковое выражение.
|
* e_choice или e_if требовало бы их обрамления какими-либо конструкциями, преобразующими их в строковое выражение.
|
||||||
|
|
@ -738,6 +958,26 @@ struct expr_choice_one_lit {
|
||||||
* e_choice(condition, "false", "true");
|
* e_choice(condition, "false", "true");
|
||||||
* e_if(!condition, "empty");
|
* e_if(!condition, "empty");
|
||||||
* ```
|
* ```
|
||||||
|
* @en @brief Conditional selection string expression.
|
||||||
|
* @en @details An expression that, depending on the truth of the condition, generates either one string literal or another.
|
||||||
|
* The type is usually not used directly; it is created via e_choice().
|
||||||
|
*
|
||||||
|
* Since string literals are not string expressions, use them as a single expression in parts
|
||||||
|
* e_choice or e_if would require them to be surrounded by some constructs that convert them to a string expression.
|
||||||
|
* You would have to write something like this:
|
||||||
|
* ```cpp
|
||||||
|
* e_choice(condition, text, e_t("empty"));
|
||||||
|
* e_choice(condition, text, eea + "empty");
|
||||||
|
* e_choice(condition, text, "empty"_ss);
|
||||||
|
* e_if(!condition, "empty"_ss);
|
||||||
|
* ```
|
||||||
|
* This, on the one hand, clutters up the code, on the other, makes it less optimal.
|
||||||
|
* These overloads use expr_choice_one_lit and expr_choice_two_lit, allowing you to write like this:
|
||||||
|
* ```cpp
|
||||||
|
* e_choice(condition, text, "empty");
|
||||||
|
* e_choice(condition, "false", "true");
|
||||||
|
* e_if(!condition, "empty");
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
template<typename K, size_t N, size_t M>
|
template<typename K, size_t N, size_t M>
|
||||||
struct expr_choice_two_lit {
|
struct expr_choice_two_lit {
|
||||||
|
|
@ -764,24 +1004,33 @@ struct expr_choice_two_lit {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Создание условного строкового выражения expr_choice
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @tparam A - Тип выражение при истинности условия, выводится из аргумента
|
* @ru @brief Создание условного строкового выражения expr_choice.
|
||||||
* @tparam B - Тип выражения при ложности условия, выводится из аргумента
|
* @ru @tparam A - Тип выражение при истинности условия, выводится из аргумента.
|
||||||
* @param c - булево условие
|
* @ru @tparam B - Тип выражения при ложности условия, выводится из аргумента.
|
||||||
* @param a - строковое выражение, выполняющееся при `c == true`
|
* @ru @param c - булево условие.
|
||||||
* @param b - строковое выражение, выполняющееся при `c == false`
|
* @ru @param a - строковое выражение, выполняющееся при `c == true`.
|
||||||
* @details Служит для возможности в одном выражении выбирать разные варианты в зависимости от условия.
|
* @ru @param b - строковое выражение, выполняющееся при `c == false`.
|
||||||
|
* @ru @details Служит для возможности в одном выражении выбирать разные варианты в зависимости от условия.
|
||||||
|
* @en @brief Create a conditional string expression expr_choice.
|
||||||
|
* @en @tparam A - Type expression when the condition is true, inferred from the argument.
|
||||||
|
* @en @tparam B - The type of expression when the condition is false, inferred from the argument.
|
||||||
|
* @en @param c is a Boolean condition.
|
||||||
|
* @en @param a is a string expression that is executed when `c == true`.
|
||||||
|
* @en @param b is a string expression that is executed when `c == false`.
|
||||||
|
* @en @details Serves to allow you to select different options in one expression depending on the condition.
|
||||||
*
|
*
|
||||||
* Примеры:
|
* @ru Примеры: @en Example: @~
|
||||||
* ```cpp
|
* ```cpp
|
||||||
* columns_metadata.emplace_back(e_choice(name.is_empty(), "?column?", name) + "::" + metadata_column.type.to_string());
|
* columns_metadata.emplace_back(e_choice(name.is_empty(), "?column?", name) + "::" + metadata_column.type.to_string());
|
||||||
* ```
|
* ```
|
||||||
* ```cpp
|
* ```cpp
|
||||||
* lstringa<512> str = e_choice(!ret_type_resolver_, sql_value::type_name(ret_type_), "any") + " " + name_ + "(";
|
* lstringa<512> str = e_choice(!ret_type_resolver_, sql_value::type_name(ret_type_), "any") + " " + name_ + "(";
|
||||||
* ```
|
* ```
|
||||||
* Иначе такие операции приходилось бы разбивать на несколько модификаций строки или применению временных строк,
|
* @ru Иначе такие операции приходилось бы разбивать на несколько модификаций строки или применению временных строк,
|
||||||
* что не оптимально и снизит производительность. (Это проверяется в бенчмарке "Build Full Func Name")
|
* что не оптимально и снизит производительность. (Это проверяется в бенчмарке "Build Full Func Name")
|
||||||
|
* @en Otherwise, such operations would have to be split into several string modifications or the use of temporary strings,
|
||||||
|
* which is not optimal and will reduce performance. (This is checked in the "Build Full Func Name" benchmark)
|
||||||
*/
|
*/
|
||||||
template<StrExpr A, StrExprForType<typename A::symb_type> B>
|
template<StrExpr A, StrExprForType<typename A::symb_type> B>
|
||||||
inline constexpr auto e_choice(bool c, const A& a, const B& b) {
|
inline constexpr auto e_choice(bool c, const A& a, const B& b) {
|
||||||
|
|
@ -789,8 +1038,9 @@ inline constexpr auto e_choice(bool c, const A& a, const B& b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Перегрузка e_choice, когда третий аргумент - строковый литерал
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Перегрузка e_choice, когда третий аргумент - строковый литерал.
|
||||||
|
* @en @brief Overload e_choice when the third argument is a string literal.
|
||||||
*/
|
*/
|
||||||
template<StrExpr A, typename T, size_t N = const_lit_for<typename A::symb_type, T>::Count>
|
template<StrExpr A, typename T, size_t N = const_lit_for<typename A::symb_type, T>::Count>
|
||||||
inline constexpr auto e_choice(bool c, const A& a, T&& str) {
|
inline constexpr auto e_choice(bool c, const A& a, T&& str) {
|
||||||
|
|
@ -798,16 +1048,18 @@ inline constexpr auto e_choice(bool c, const A& a, T&& str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Перегрузка e_choice, когда второй аргумент - строковый литерал
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Перегрузка e_choice, когда второй аргумент - строковый литерал.
|
||||||
|
* @en @brief Overload e_choice when the second argument is a string literal.
|
||||||
*/
|
*/
|
||||||
template<StrExpr A, typename T, size_t N = const_lit_for<typename A::symb_type, T>::Count>
|
template<StrExpr A, typename T, size_t N = const_lit_for<typename A::symb_type, T>::Count>
|
||||||
inline constexpr auto e_choice(bool c, T&& str, const A& a) {
|
inline constexpr auto e_choice(bool c, T&& str, const A& a) {
|
||||||
return expr_choice_one_lit<A, N - 1, false>{str, a, c};
|
return expr_choice_one_lit<A, N - 1, false>{str, a, c};
|
||||||
}
|
}
|
||||||
/*!
|
/*!
|
||||||
* @brief Перегрузка e_choice, когда второй и третий аргумент - строковые литералы
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Перегрузка e_choice, когда второй и третий аргумент - строковые литералы.
|
||||||
|
* @en @brief Overload e_choice when the second and third arguments are string literals.
|
||||||
*/
|
*/
|
||||||
template<typename T, typename L, size_t N = const_lit<T>::Count, size_t M = const_lit_for<typename const_lit<T>::symb_type, L>::Count>
|
template<typename T, typename L, size_t N = const_lit<T>::Count, size_t M = const_lit_for<typename const_lit<T>::symb_type, L>::Count>
|
||||||
inline constexpr auto e_choice(bool c, T&& str_a, L&& str_b) {
|
inline constexpr auto e_choice(bool c, T&& str_a, L&& str_b) {
|
||||||
|
|
@ -815,43 +1067,56 @@ inline constexpr auto e_choice(bool c, T&& str_a, L&& str_b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Создание условного строкового выражения expr_if
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @tparam A - Тип выражение при истинности условия, выводится из аргумента
|
* @ru @brief Создание условного строкового выражения expr_if
|
||||||
* @param c - булево условие
|
* @ru @tparam A - Тип выражение при истинности условия, выводится из аргумента
|
||||||
* @param a - строковое выражение, выполняющееся при `c == true`
|
* @ru @param c - булево условие
|
||||||
* @details Служит для возможности в одном выражении генерировать в зависимости от условия либо указанный вариант, либо пустую строку.
|
* @ru @param a - строковое выражение, выполняющееся при `c == true`
|
||||||
|
* @ru @details Служит для возможности в одном выражении генерировать в зависимости от условия либо указанный вариант, либо пустую строку.
|
||||||
|
* @en @brief Creating a conditional string expression expr_if
|
||||||
|
* @en @ingroup StrExprs
|
||||||
|
* @en @tparam A - Type expression when the condition is true, inferred from the argument
|
||||||
|
* @en @param c - boolean condition
|
||||||
|
* @en @param a - string expression executed when `c == true`
|
||||||
|
* @en @details Serves to allow one expression to generate, depending on the condition, either the specified option or an empty string.
|
||||||
*
|
*
|
||||||
* Примеры:
|
* @ru Примеры: @en Example @~
|
||||||
* ```cpp
|
* ```cpp
|
||||||
* void sql_func_info::build_full_name() {
|
* void sql_func_info::build_full_name() {
|
||||||
* // Временный буфер для результата, возьмём с запасом
|
* // Временный буфер для результата, возьмём с запасом
|
||||||
|
* // Temporary buffer for the result, take it with reserve
|
||||||
* lstringa<512> str = e_choice(!ret_type_resolver_, sql_value::type_name(ret_type_), "any") + " " + name_ + "(";
|
* lstringa<512> str = e_choice(!ret_type_resolver_, sql_value::type_name(ret_type_), "any") + " " + name_ + "(";
|
||||||
*
|
*
|
||||||
* bool add_comma = false;
|
* bool add_comma = false;
|
||||||
*
|
*
|
||||||
* for (const auto& param : params_) {
|
* for (const auto& param : params_) {
|
||||||
* str += e_if(add_comma, ", ") + e_if(param.optional_, "[");
|
* str += e_if(add_comma, ", ") + e_if(param.optional_, "[");
|
||||||
* param.allowed_types.to_string(str); // Добавляет к str названия допустимых типов
|
* // Добавляет к str названия допустимых типов
|
||||||
|
* // Adds the names of valid types to str
|
||||||
|
* param.allowed_types.to_string(str);
|
||||||
* if (param.optional_) {
|
* if (param.optional_) {
|
||||||
* str += "]";
|
* str += "]";
|
||||||
* }
|
* }
|
||||||
* add_comma = true;
|
* add_comma = true;
|
||||||
* }
|
* }
|
||||||
* // Сохраним в stringa
|
* // Сохраним в stringa
|
||||||
|
* // Save it in stringa
|
||||||
* full_name_ = str + e_if(unlim_params_, e_if(add_comma, ", ") + "...") + ")";
|
* full_name_ = str + e_if(unlim_params_, e_if(add_comma, ", ") + "...") + ")";
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
* Иначе такие операции приходилось бы разбивать на несколько модификаций строки или применению временных строк,
|
* @ru Иначе такие операции приходилось бы разбивать на несколько модификаций строки или применению временных строк,
|
||||||
* что не оптимально и снизит производительность. (Этот пример проверяется в бенчмарке "Build Full Func Name")
|
* что не оптимально и снизит производительность. (Этот пример проверяется в бенчмарке "Build Full Func Name")
|
||||||
|
* @en Otherwise, such operations would have to be split into several string modifications or the use of temporary strings,
|
||||||
|
* which is not optimal and will reduce performance. (This example is tested in the "Build Full Func Name" benchmark)
|
||||||
*/
|
*/
|
||||||
template<StrExpr A>
|
template<StrExpr A>
|
||||||
inline constexpr auto e_if(bool c, const A& a) {
|
inline constexpr auto e_if(bool c, const A& a) {
|
||||||
return expr_if<A>{a, c};
|
return expr_if<A>{a, c};
|
||||||
}
|
}
|
||||||
/*!
|
/*!
|
||||||
* @brief Перегрузка e_if, когда второй аргумент - строковый литерал
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Перегрузка e_if, когда второй аргумент - строковый литерал.
|
||||||
|
* @en @brief Overload e_if when the second argument is a string literal.
|
||||||
*/
|
*/
|
||||||
template<typename T, size_t N = const_lit<T>::Count>
|
template<typename T, size_t N = const_lit<T>::Count>
|
||||||
inline constexpr auto e_if(bool c, T&& str) {
|
inline constexpr auto e_if(bool c, T&& str) {
|
||||||
|
|
@ -860,10 +1125,13 @@ inline constexpr auto e_if(bool c, T&& str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Тип для использования std::string и std::string_view как источников в строковых выражениях
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
* @tparam K - тип символа
|
* @ru @brief Тип для использования std::string и std::string_view как источников в строковых выражениях.
|
||||||
* @tparam T - тип источника
|
* @ru @tparam K - тип символа.
|
||||||
|
* @ru @tparam T - тип источника.
|
||||||
|
* @en @brief A type for using std::string and std::string_view as sources in string expressions.
|
||||||
|
* @en @tparam K is a symbol.
|
||||||
|
* @en @tparam T - source type.
|
||||||
*/
|
*/
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
struct expr_stdstr {
|
struct expr_stdstr {
|
||||||
|
|
@ -883,8 +1151,9 @@ struct expr_stdstr {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор сложения для char строкового выражения и std::string
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Оператор сложения для char строкового выражения и std::string.
|
||||||
|
* @en @brief Addition operator for char string expression and std::string.
|
||||||
*/
|
*/
|
||||||
template<StrExprForType<u8s> A>
|
template<StrExprForType<u8s> A>
|
||||||
auto operator+(const A& a, const std::string& s) {
|
auto operator+(const A& a, const std::string& s) {
|
||||||
|
|
@ -892,8 +1161,9 @@ auto operator+(const A& a, const std::string& s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор сложения для std::string и char строкового выражения
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Оператор сложения для std::string и char строкового выражения.
|
||||||
|
* @en @brief Addition operator for std::string and char string expression.
|
||||||
*/
|
*/
|
||||||
template<StrExprForType<u8s> A>
|
template<StrExprForType<u8s> A>
|
||||||
auto operator+(const std::string& s, const A& a) {
|
auto operator+(const std::string& s, const A& a) {
|
||||||
|
|
@ -901,8 +1171,9 @@ auto operator+(const std::string& s, const A& a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор сложения для char строкового выражения и std::string_view
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Оператор сложения для char строкового выражения и std::string_view.
|
||||||
|
* @en @brief Addition operator for char string expression and std::string_view.
|
||||||
*/
|
*/
|
||||||
template<StrExprForType<u8s> A>
|
template<StrExprForType<u8s> A>
|
||||||
auto operator+(const A& a, const std::string_view& s) {
|
auto operator+(const A& a, const std::string_view& s) {
|
||||||
|
|
@ -910,8 +1181,9 @@ auto operator+(const A& a, const std::string_view& s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор сложения для std::string_view и char строкового выражения
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Оператор сложения для std::string_view и char строкового выражения.
|
||||||
|
* @en @brief Addition operator for std::string_view and char string expression.
|
||||||
*/
|
*/
|
||||||
template<StrExprForType<u8s> A>
|
template<StrExprForType<u8s> A>
|
||||||
auto operator+(const std::string_view& s, const A& a) {
|
auto operator+(const std::string_view& s, const A& a) {
|
||||||
|
|
@ -919,8 +1191,9 @@ auto operator+(const std::string_view& s, const A& a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор сложения для wchar_t строкового выражения и std::wstring
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Оператор сложения для wchar_t строкового выражения и std::wstring.
|
||||||
|
* @en @brief Addition operator for wchar_t string expression and std::wstring.
|
||||||
*/
|
*/
|
||||||
template<StrExprForType<uws> A>
|
template<StrExprForType<uws> A>
|
||||||
auto operator+(const A& a, const std::wstring& s) {
|
auto operator+(const A& a, const std::wstring& s) {
|
||||||
|
|
@ -928,8 +1201,9 @@ auto operator+(const A& a, const std::wstring& s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор сложения для std::wstring и wchar_t строкового выражения
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Оператор сложения для std::wstring и wchar_t строкового выражения.
|
||||||
|
* @en @brief Addition operator for std::wstring and wchar_t string expression.
|
||||||
*/
|
*/
|
||||||
template<StrExprForType<uws> A>
|
template<StrExprForType<uws> A>
|
||||||
auto operator+(const std::wstring& s, const A& a) {
|
auto operator+(const std::wstring& s, const A& a) {
|
||||||
|
|
@ -937,8 +1211,9 @@ auto operator+(const std::wstring& s, const A& a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор сложения для wchar_t строкового выражения и std::wstring_view
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Оператор сложения для wchar_t строкового выражения и std::wstring_view.
|
||||||
|
* @en @brief Addition operator for wchar_t string expression and std::wstring_view.
|
||||||
*/
|
*/
|
||||||
template<StrExprForType<uws> A>
|
template<StrExprForType<uws> A>
|
||||||
auto operator+(const A& a, const std::wstring_view& s) {
|
auto operator+(const A& a, const std::wstring_view& s) {
|
||||||
|
|
@ -946,8 +1221,9 @@ auto operator+(const A& a, const std::wstring_view& s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор сложения для std::wstring_view и wchar_t строкового выражения
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Оператор сложения для std::wstring_view и wchar_t строкового выражения.
|
||||||
|
* @en @brief Addition operator for std::wstring_view and wchar_t string expression.
|
||||||
*/
|
*/
|
||||||
template<StrExprForType<uws> A>
|
template<StrExprForType<uws> A>
|
||||||
auto operator+(const std::wstring_view& s, const A& a) {
|
auto operator+(const std::wstring_view& s, const A& a) {
|
||||||
|
|
@ -955,9 +1231,11 @@ auto operator+(const std::wstring_view& s, const A& a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор сложения для совместимого с wchar_t строкового выражения (char16_t или
|
|
||||||
* char32_t, в зависимости от компилятора) и std::wstring
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Оператор сложения для совместимого с wchar_t строкового выражения (char16_t или
|
||||||
|
* char32_t, в зависимости от компилятора) и std::wstring.
|
||||||
|
* @en @brief Addition operator for wchar_t compatible string expression (char16_t or
|
||||||
|
* char32_t, depending on the compiler) and std::wstring.
|
||||||
*/
|
*/
|
||||||
template<StrExprForType<wchar_type> A>
|
template<StrExprForType<wchar_type> A>
|
||||||
auto operator+(const A& a, const std::wstring& s) {
|
auto operator+(const A& a, const std::wstring& s) {
|
||||||
|
|
@ -965,9 +1243,11 @@ auto operator+(const A& a, const std::wstring& s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор сложения для std::wstring и совместимого с wchar_t строкового выражения
|
|
||||||
* (char16_t или char32_t, в зависимости от компилятора)
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Оператор сложения для std::wstring и совместимого с wchar_t строкового выражения
|
||||||
|
* (char16_t или char32_t, в зависимости от компилятора).
|
||||||
|
* @en @brief Addition operator for std::wstring and wchar_t-compatible string expression
|
||||||
|
* (char16_t or char32_t, depending on the compiler).
|
||||||
*/
|
*/
|
||||||
template<StrExprForType<wchar_type> A>
|
template<StrExprForType<wchar_type> A>
|
||||||
auto operator+(const std::wstring& s, const A& a) {
|
auto operator+(const std::wstring& s, const A& a) {
|
||||||
|
|
@ -975,9 +1255,11 @@ auto operator+(const std::wstring& s, const A& a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор сложения для совместимого с wchar_t строкового выражения (char16_t или
|
|
||||||
* char32_t, в зависимости от компилятора) и std::wstring_view
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Оператор сложения для совместимого с wchar_t строкового выражения (char16_t или
|
||||||
|
* char32_t, в зависимости от компилятора) и std::wstring_view.
|
||||||
|
* @en @brief Addition operator for wchar_t compatible string expression (char16_t or
|
||||||
|
* char32_t, depending on the compiler) and std::wstring_view.
|
||||||
*/
|
*/
|
||||||
template<StrExprForType<wchar_type> A>
|
template<StrExprForType<wchar_type> A>
|
||||||
auto operator+(const A& a, const std::wstring_view& s) {
|
auto operator+(const A& a, const std::wstring_view& s) {
|
||||||
|
|
@ -985,9 +1267,11 @@ auto operator+(const A& a, const std::wstring_view& s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Оператор сложения для std::wstring_view и совместимого с wchar_t строкового выражения
|
|
||||||
* (char16_t или char32_t, в зависимости от компилятора)
|
|
||||||
* @ingroup StrExprs
|
* @ingroup StrExprs
|
||||||
|
* @ru @brief Оператор сложения для std::wstring_view и совместимого с wchar_t строкового выражения
|
||||||
|
* (char16_t или char32_t, в зависимости от компилятора).
|
||||||
|
* @en @brief Addition operator for std::wstring_view and wchar_t-compatible string expression
|
||||||
|
* (char16_t or char32_t, depending on the compiler).
|
||||||
*/
|
*/
|
||||||
template<StrExprForType<wchar_type> A>
|
template<StrExprForType<wchar_type> A>
|
||||||
auto operator+(const std::wstring_view& s, const A& a) {
|
auto operator+(const std::wstring_view& s, const A& a) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue