diff --git a/CMakeLists.txt b/CMakeLists.txt index 267d251..3691acc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ include(FetchContent) project( simstr - VERSION 1.8.2 + VERSION 1.9.1 DESCRIPTION "Yet another modern C++ string library" HOMEPAGE_URL "https://github.com/orefkov/simstr" LANGUAGES CXX diff --git a/bench/bench_str.cpp b/bench/bench_str.cpp index 8aac7f5..251df3d 100644 --- a/bench/bench_str.cpp +++ b/bench/bench_str.cpp @@ -1,5 +1,5 @@ /* - * ver. 1.8.2 + * ver. 1.9.1 * (c) Проект "SimStr", Александр Орефков orefkov@gmail.com * Бенчмарки * (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com diff --git a/bench/process_result.cpp b/bench/process_result.cpp index 782f66b..db4956c 100644 --- a/bench/process_result.cpp +++ b/bench/process_result.cpp @@ -38,7 +38,7 @@ struct result_info { } // Текущее положение поставим сразу за 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_.get(cpu_info_.end() - current_text_.begin() + 1, to_end).trimmed_right("\n"); } }; @@ -96,11 +96,11 @@ results_vector get_results_infos() { // В начале имени файла может идти число и дефис, для сортировки, уберём их // At the beginning of the file name there can be a number and a hyphen, for sorting, remove them if (auto delimiter = fileName.find('-'); delimiter + 1 > 1) { - if (fileName(0, delimiter).to_int().ec == IntConvertResult::Success) { + if (fileName.prefix(delimiter).to_int().ec == IntConvertResult::Success) { fileName.remove_prefix(delimiter + 1); } } - results.emplace_back(get_file_content(lstringa<128>{dirForResults + f}), fileName(0, -suffix.length())); + results.emplace_back(get_file_content(lstringa<128>{dirForResults + f}), fileName.get(0, from_end(suffix.length()))); } } return results; @@ -117,7 +117,7 @@ void write_platforms_cpu(out_t& out, const results_vector& results) { for (const auto& r : results) { size_t rp = r.cpu_info_.find('(') + 1, lp = r.cpu_info_.find(')', rp); ssa shortCpuInfo = r.cpu_info_.from_to(rp, lp); - ssa cpuInfo = r.cpu_info_(lp + 2); + ssa cpuInfo = r.cpu_info_.get(lp + 2, to_end); out += e_subst(R"--(
  • {}{}{} Include in charts:
  • )--", r.platform_, shortCpuInfo, cpuInfo, counter++); @@ -167,7 +167,7 @@ ssa extract_name_result(ssa line, ssa& result) { line.len = ns; if (inNs) { size_t end = line.find_last(' '); - result = line(end + 1); + result = line.get(end + 1, to_end); if (auto rp = line.find("/repeats"); rp != str::npos) { line.len = rp; } else { @@ -182,7 +182,7 @@ ssa extract_name_result(ssa line, ssa& result) { ssa extract_comment(ssa commentsText, ssa benchmarkName) { size_t idx = commentsText.find_end(lstringa<120>{"- " + benchmarkName + "\n"}); if (idx != str::npos) { - if (commentsText[idx] != '\n' && commentsText(idx, 2) != "- ") { + if (commentsText[idx] != '\n' && commentsText.get(idx, 2) != "- ") { return commentsText.from_to(idx, commentsText.find("\n\n", idx)); } } @@ -206,7 +206,7 @@ std::pair extract_source_for_benchmark(ssa benchName, ssa sourceTex }(); size_t delim = benchName.find_last('/'); - if (delim != str::npos && benchName(delim + 1).to_int().ec == IntConvertResult::Success) { + if (delim != str::npos && benchName.get(delim + 1, to_end).to_int().ec == IntConvertResult::Success) { benchName.len = delim; } auto [it, not_exist] = textes.try_emplace(benchName, stringa{}, 0); @@ -218,7 +218,7 @@ std::pair extract_source_for_benchmark(ssa benchName, ssa sourceTex std::cerr << "Can not found benchmark function name for " << benchName << std::endl; return {stra::empty_str, 0}; } - start = sourceText(0, start).find('(', sourceText.find_last('\n', start - 1)); + start = sourceText.prefix(start).find('(', sourceText.find_last('\n', start - 1)); if (start == str::npos) { std::cerr << "Can not found benchmark function name for " << benchName << std::endl; return {stra::empty_str, 0}; @@ -237,7 +237,7 @@ std::pair extract_source_for_benchmark(ssa benchName, ssa sourceTex } start = sourceText.find_last('\n', start); size_t templ_start = sourceText.find_last('\n', start) + 1; - if (sourceText(templ_start).starts_with("template")) { + if (sourceText.get(templ_start, to_end).starts_with("template")) { start = templ_start; } else { start++; @@ -261,7 +261,7 @@ std::pair extract_source_for_benchmark(ssa benchName, ssa sourceTex throw std::runtime_error{"Not found end of func"}; } lstringa<2048> text{sourceText.from_to(beginLine, end + indent.length() + 1), indent, "\n"}; - func_it->second.first = repl_html_symbols(text(1)); + func_it->second.first = repl_html_symbols(text.get(1, to_end)); } else { end = sourceText.find("\n}\n", start); func_it->second.first = repl_html_symbols(sourceText.from_to(start, end + 2)); @@ -274,7 +274,7 @@ std::pair extract_source_for_benchmark(ssa benchName, ssa sourceTex } void write_benchmarks(out_t& out, const results_vector& results, ssa sourceText, ssa commentsText) { - ssa releaseVersion = sourceText(sourceText.find_end("\n * ver. ")).until("\n").trimmed(); + ssa releaseVersion = sourceText.get(sourceText.find_end("\n * ver. "), to_end).until("\n").trimmed(); if (!releaseVersion) { std::cerr << "Not found release version in sources" << std::endl; throw std::runtime_error{"Not found release version in sources"}; @@ -292,7 +292,7 @@ void write_benchmarks(out_t& out, const results_vector& results, ssa sourceText, while(!splitters[0].is_done()) { ssa line = splitters[0].next(), benchName, result; if (auto rm = line.find("_mean"); rm != str::npos) { - benchName = extract_name_result(line, result)(0, rm); + benchName = extract_name_result(line, result).prefix(rm); auto [source, line_num] = extract_source_for_benchmark(benchName, sourceText); auto comment = extract_comment(commentsText, benchName); // Нужно вывести название бенча и коммент @@ -312,12 +312,12 @@ void write_benchmarks(out_t& out, const results_vector& results, ssa sourceText, throw std::runtime_error{"Not expected end of file"}; } line = splitters[idx].next(); - ssa rbench_name = extract_name_result(line, result)(0, rm); + ssa rbench_name = extract_name_result(line, result).prefix(rm); if (rbench_name != benchName) { while (line.find("_mean") == str::npos && !splitters[idx].is_done()) { line = splitters[idx].next(); } - rbench_name = extract_name_result(line, result)(0, rm); + rbench_name = extract_name_result(line, result).prefix(rm); if (rbench_name != benchName) { std::cerr << "In results for " << results[idx].platform_ << " benchmark '" << rbench_name << "' does not match with other results" << std::endl; diff --git a/docs/Doxyfile b/docs/Doxyfile index fa30426..592f70d 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -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.8.2 +PROJECT_NUMBER = 1.9.1 # 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 diff --git a/docs/Doxyfile_ru b/docs/Doxyfile_ru index 96ec69b..c80c39f 100644 --- a/docs/Doxyfile_ru +++ b/docs/Doxyfile_ru @@ -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.8.2 +PROJECT_NUMBER = 1.9.1 # 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 diff --git a/include/simstr/simple_unicode.h b/include/simstr/simple_unicode.h index 1606df7..9f33712 100644 --- a/include/simstr/simple_unicode.h +++ b/include/simstr/simple_unicode.h @@ -1,6 +1,6 @@ /* * (c) Проект "SimStr", Александр Орефков orefkov@gmail.com - * ver. 1.8.2 + * ver. 1.9.1 */ #pragma once diff --git a/include/simstr/sstring.h b/include/simstr/sstring.h index bcce62a..791b198 100644 --- a/include/simstr/sstring.h +++ b/include/simstr/sstring.h @@ -1,5 +1,5 @@ /* -* ver. 1.8.2 +* ver. 1.9.1 * (c) Проект "SimStr", Александр Орефков orefkov@gmail.com * Классы для работы со строками * (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com diff --git a/include/simstr/strexpr.h b/include/simstr/strexpr.h index 0ea6ea9..7d786e4 100644 --- a/include/simstr/strexpr.h +++ b/include/simstr/strexpr.h @@ -1,5 +1,5 @@ /* - * ver. 1.8.2 + * ver. 1.9.1 * (c) Проект "SimStr", Александр Орефков orefkov@gmail.com * База для строковых конкатенаций через выражения времени компиляции * (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com @@ -3274,6 +3274,20 @@ public: } }; +struct from_begin { + size_t idx_; +}; +struct from_end { + size_t idx_; +}; +inline constexpr from_end to_end{0}; + +template +concept first_index_in_str = std::is_same_v || std::is_convertible_v; + +template +concept last_index_in_str = first_index_in_str || std::is_same_v; + /*! * @ru @brief Класс с базовыми константными строковыми алгоритмами. * @details Является базой для классов, могущих выполнять константные операции со строками. @@ -3445,6 +3459,7 @@ public: * "0123456789"_ss(-4, -1) == "678"; * ``` */ + [[deprecated("Use 'get' or [start, end] in C++23")]] constexpr str_piece operator()(ptrdiff_t from, ptrdiff_t len = 0) const noexcept { size_t myLen = _len(), idxStart = from >= 0 ? from : (ptrdiff_t)myLen > -from ? myLen + from : 0, idxEnd = len > 0 ? idxStart + len : (ptrdiff_t)myLen > -len ? myLen + len : 0; @@ -3454,6 +3469,83 @@ public: idxStart = idxEnd; return str_piece{_str() + idxStart, idxEnd - idxStart}; } + + /*! + * @ru @brief Получить часть строки как "str_src". + * @param start - начальная позиция в строке. + * @param end - конечная позиция в строке. + * @return Подстроку, str_src. + * @details В качестве начальной позиции может задаваться или число - отсчитывается от начала строки, но не далее её конца, + * или `from_end(число)` - отсчитывается от конца строки, но не ранее её начала. + * В качестве конечной позиции может задаваться или число - отсчитывается от начальной позиции, но не далее конца строки, + * или `from_end(число)` - отсчитывается от конца строки, но не ранее начальной позиции, + * или `from_begin(число)` - отсчитывается от начала строки, но не ранее начальной позиции и не далее конца строки. + * Также можно использовать `to_end` - эквивалентно from_end(0). + * @en @brief Get part of a string as "str_src". + * @param start - starting position in the string. + * @param end - the end position in the string. + * @return Substring, str_src. + * @details Either a number can be specified as the starting position - it is counted from the beginning of the string, but not further than its end, + * or `from_end(number)` - counted from the end of the string, but not earlier than its beginning. + * The ending position can be either a number - counted from the starting position, but not further than the end of the string, + * or `from_end(number)` - counted from the end of the string, but not earlier than the starting position, + * or `from_begin(number)` - counted from the beginning of the string, but not earlier than the starting position and not further than the end of the string. + * You can also use `to_end` - equivalent to from_end(0). + * @~ + * ```cpp + * "0123456789"_ss.get(5, 2) == "56"; + * "0123456789"_ss.get(5, to_end) == "56789"; + * "0123456789"_ss.get(5, from_end(1)) == "5678"; + * "0123456789"_ss.get(from_end(3), to_end) == "789"; + * "0123456789"_ss.get(from_end(3), 2) == "78"; + * "0123456789"_ss.get(from_end(4), from_end(1)) == "678"; + * ``` + */ + template + constexpr str_piece get(S start, E end) const noexcept { + size_t idxStart, idxEnd, len = _len(); + if constexpr (std::is_same_v) { + idxStart = start.idx_ > len ? 0 : len - start.idx_; + } else { + idxStart = std::min(size_t(start), len); + } + + if constexpr (std::is_same_v) { + idxEnd = std::max(idxStart, std::min(end.idx_, len)); + } else if constexpr (std::is_same_v) { + idxEnd = std::max(idxStart, end.idx_ > len ? 0 : len - end.idx_); + } else { + size_t e = end; + idxEnd = len - idxStart < e ? len : idxStart + e; + } + + return str_piece{_str() + idxStart, idxEnd - idxStart}; + } + +#if defined(__cpp_multidimensional_subscript) && __cpp_multidimensional_subscript >= 202211L + /*! + * @ru @brief Обертка вокруг `get` в виде многомерного оператора []. + * @en @brief Wraps `get` as a multidimensional operator []. + */ + template + constexpr str_piece operator[](S start, E end) const noexcept { + return get(start, end); + } +#endif + /*! + * @ru @brief Обертка вокруг `get(0, count)`. + * @en @brief Wraps `get(0, count)`. + */ + constexpr str_piece prefix(size_t count) const noexcept { + return get(0, count); + } + /*! + * @ru @brief Обертка вокруг `get(from_end(count), to_end)`. + * @en @brief Wraps `get(from_end(count), to_end)`. + */ + constexpr str_piece suffix(size_t count) const noexcept { + return get(from_end(count), to_end); + } /*! * @ru @brief Получить часть строки как "кусок строки". * @param from - количество символов от начала строки. При превышении размера строки вернёт пустую строку. @@ -3500,7 +3592,7 @@ public: * @return Substring, str_src. */ constexpr str_piece until(str_piece pattern, size_t offset = 0) const noexcept { - return (*this)(0, find_or_all(pattern, offset)); + return get(0, find_or_all(pattern, offset)); } /*! * @ru @brief Проверка на пустоту. @@ -4071,9 +4163,14 @@ public: * @param len - the number of characters in the resulting "chunk". If less than or equal to zero, then count len ​​characters from the end of the string. * @return my_type - a substring, an object of the same type to which the method is applied. */ + [[deprecated("Use sub(start, end)")]] constexpr my_type substr(ptrdiff_t from, ptrdiff_t len = 0) const { // индексация в code units | indexing in code units return my_type{d()(from, len)}; } + template + constexpr my_type sub(S start, E end) const noexcept { + return my_type{get(start, end)}; + } /*! * @ru @brief Получить часть строки объектом того же типа, к которому применён метод, аналогично mid. * @param from - количество символов от начала строки. При превышении размера строки вернёт пустую строку. @@ -4597,7 +4694,7 @@ public: template constexpr std::optional strip_prefix(str_piece prefix) const { if (starts_with(prefix)) { - return R{operator()(prefix.length())}; + return R{get(prefix.length(), to_end)}; } return {}; } @@ -4616,7 +4713,7 @@ public: template constexpr std::optional strip_prefix_ia(str_piece prefix) const { if (starts_with_ia(prefix)) { - return R{operator()(prefix.length())}; + return R{get(prefix.length(), to_end)}; } return {}; } @@ -4635,7 +4732,7 @@ public: template constexpr std::optional strip_suffix(str_piece suffix) const { if (ends_with(suffix)) { - return R{operator()(0, -suffix.length())}; + return R{get(0, from_end{suffix.length()})}; } return {}; } @@ -4654,7 +4751,7 @@ public: template constexpr std::optional strip_suffix_ia(str_piece suffix) const { if (ends_with_ia(suffix)) { - return R{operator()(0, -suffix.length())}; + return R{get(0, from_end{suffix.length()})}; } return {}; } @@ -4939,7 +5036,7 @@ public: constexpr R trimmed_prefix(str_piece prefix, size_t max_count = 0) const { str_piece res = *this; while(res.starts_with(prefix)) { - res = res(prefix.length()); + res.remove_prefix(prefix.length()); if (--max_count == 0) { break; } @@ -4962,7 +5059,7 @@ public: constexpr R trimmed_prefix_ia(str_piece prefix, size_t max_count = 0) const { str_piece res = *this; while(res.starts_with_ia(prefix)) { - res = res(prefix.length()); + res.remove_prefix(prefix.length()); if (--max_count == 0) { break; } @@ -4985,7 +5082,7 @@ public: constexpr R trimmed_suffix(str_piece suffix) const { str_piece res = *this; while(res.ends_with(suffix)) { - res = res(0, -suffix.length()); + res.remove_suffix(suffix.length()); } return res; } @@ -5005,7 +5102,7 @@ public: constexpr R trimmed_suffix_ia(str_piece suffix) const { str_piece res = *this; while(res.ends_with_ia(suffix)) { - res = res(0, -suffix.length()); + res.remove_suffix(suffix.length()); } return res; } diff --git a/readme.md b/readme.md index 0375c11..dc741e5 100644 --- a/readme.md +++ b/readme.md @@ -3,7 +3,7 @@ [![CMake on multiple platforms](https://github.com/orefkov/simstr/actions/workflows/cmake-multi-platform.yml/badge.svg)](https://github.com/orefkov/simstr/actions/workflows/cmake-multi-platform.yml) -Version 1.8.2. +Version 1.9.1

    Speed up your work with strings by 2-10 times!

    @@ -325,8 +325,8 @@ function(add_simstr) simstr GIT_REPOSITORY https://github.com/orefkov/simstr.git GIT_SHALLOW TRUE - GIT_TAG tags/rel1.8.2 # Specify the desired release - FIND_PACKAGE_ARGS NAMES simstr 1.8.2 + GIT_TAG tags/rel1.9.1# Specify the desired release + FIND_PACKAGE_ARGS NAMES simstr 1.9.1 ) FetchContent_MakeAvailable(simstr) endfunction() diff --git a/readme_ru.md b/readme_ru.md index 82d0c55..974d958 100644 --- a/readme_ru.md +++ b/readme_ru.md @@ -3,7 +3,7 @@ [![CMake on multiple platforms](https://github.com/orefkov/simstr/actions/workflows/cmake-multi-platform.yml/badge.svg)](https://github.com/orefkov/simstr/actions/workflows/cmake-multi-platform.yml) -Версия 1.8.2. +Версия 1.9.1

    Ускорь работу со строками в 2-10 раз!

    @@ -326,8 +326,8 @@ function(add_simstr) simstr GIT_REPOSITORY https://github.com/orefkov/simstr.git GIT_SHALLOW TRUE - GIT_TAG tags/rel1.8.2 # Укажите нужный релиз - FIND_PACKAGE_ARGS NAMES simstr 1.8.2 + GIT_TAG tags/rel1.9.1# Укажите нужный релиз + FIND_PACKAGE_ARGS NAMES simstr 1.9.1 ) FetchContent_MakeAvailable(simstr) endfunction() diff --git a/src/sstring.cpp b/src/sstring.cpp index ce34efa..c162b29 100644 --- a/src/sstring.cpp +++ b/src/sstring.cpp @@ -1,5 +1,5 @@ /* - * ver. 1.8.2 + * ver. 1.9.1 * (c) Проект "SimStr", Александр Орефков orefkov@gmail.com * Реализация строковых функций * (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com diff --git a/tests/test_expr_only.cpp b/tests/test_expr_only.cpp index 129a975..63bf925 100644 --- a/tests/test_expr_only.cpp +++ b/tests/test_expr_only.cpp @@ -1,5 +1,5 @@ /* - * ver. 1.8.2 + * ver. 1.9.1 * (c) Проект "SimStr", Александр Орефков orefkov@gmail.com * Тесты simstr * (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com @@ -452,4 +452,22 @@ TEST(StrExpr, StartWithAnd) { EXPECT_TRUE("Begin[ --end"_ss.starts_with_ia_and_oneof("begin", "/*[]"_ss)); } +TEST(SimStr, Get) { + ssa testa{"test"}; + EXPECT_EQ(testa.get(1, to_end), "est"); + EXPECT_EQ(testa.get(1, 2), "es"); + EXPECT_EQ(testa.get(1, from_end(1)), "es"); + EXPECT_EQ(testa.get(1, from_end(10)), ""); + EXPECT_EQ(testa.get(from_end(3), from_end(1)), "es"); + + ssu testu{u"test"}; + EXPECT_EQ(testu.get(1, to_end), u"est"); + EXPECT_EQ(testu.get(1, 2), u"es"); + EXPECT_EQ(testu.get(from_end(3), from_end(1)), u"es"); + + ssw testw{L"test"}; + EXPECT_EQ(testw.get(1, to_end), L"est"); + EXPECT_EQ(testw.get(1, 2), L"es"); + EXPECT_EQ(testw.get(from_end(3), from_end(1)), L"es"); +} } // namespace simstr::tests diff --git a/tests/test_str.cpp b/tests/test_str.cpp index eb989ff..4f2597a 100644 --- a/tests/test_str.cpp +++ b/tests/test_str.cpp @@ -1,5 +1,5 @@ /* - * ver. 1.8.2 + * ver. 1.9.1 * (c) Проект "SimStr", Александр Орефков orefkov@gmail.com * Тесты simstr * (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com @@ -274,6 +274,7 @@ TEST(SimStr, SimpleFind) { EXPECT_EQ("abccccc"_ss.find_last("ab"), 0); } +#if 0 TEST(SimStr, SubPiece) { ssa testa{"test"}; EXPECT_EQ(testa(1), "est"); @@ -289,39 +290,83 @@ TEST(SimStr, SubPiece) { EXPECT_EQ(testw(1), L"est"); EXPECT_EQ(testw(1, 2), L"es"); } +#endif + +TEST(SimStr, Get) { + ssa testa{"test"}; + EXPECT_EQ(testa.get(1, to_end), "est"); + EXPECT_EQ(testa.get(1, 2), "es"); + EXPECT_EQ(testa.get(1, from_end(1)), "es"); + EXPECT_EQ(testa.get(1, from_end(10)), ""); + + ssu testu{u"test"}; + EXPECT_EQ(testu.get(1, to_end), u"est"); + EXPECT_EQ(testu.get(1, 2), u"es"); + + ssw testw{L"test"}; + EXPECT_EQ(testw.get(1, to_end), L"est"); + EXPECT_EQ(testw.get(1, 2), L"es"); +} TEST(SimStr, SimpleSubstr) { ssa testa = "test"; +#if 0 EXPECT_EQ(testa.substr(1, 0), "est"); EXPECT_EQ(testa.substr(1, 2), "es"); EXPECT_EQ(testa.substr(0, -1), "tes"); EXPECT_EQ(testa.substr(-2), "st"); EXPECT_EQ(testa.substr(-3, 2), "es"); EXPECT_EQ(testa.substr(-3, -1), "es"); +#endif + EXPECT_EQ(testa.sub(1, to_end), "est"); + EXPECT_EQ(testa.sub(1, 2), "es"); + EXPECT_EQ(testa.sub(0, from_end(1)), "tes"); + EXPECT_EQ(testa.sub(from_end(2), to_end), "st"); + EXPECT_EQ(testa.sub(from_end(3), 2), "es"); + EXPECT_EQ(testa.sub(from_end(3), from_end(1)), "es"); + EXPECT_EQ(testa.str_mid(1), "est"); EXPECT_EQ(testa.str_mid(1, 0), ""); EXPECT_EQ(testa.str_mid(1, 2), "es"); EXPECT_EQ(testa.str_mid(2, 2), "st"); ssu testu = u"test"; +#if 0 EXPECT_EQ(testu.substr(1, 0), u"est"); EXPECT_EQ(testu.substr(1, 2), u"es"); EXPECT_EQ(testu.substr(0, -1), u"tes"); EXPECT_EQ(testu.substr(-2), u"st"); EXPECT_EQ(testu.substr(-3, 2), u"es"); EXPECT_EQ(testu.substr(-3, -1), u"es"); +#endif + EXPECT_EQ(testu.sub(1, to_end), u"est"); + EXPECT_EQ(testu.sub(1, 2), u"es"); + EXPECT_EQ(testu.sub(0, from_end(1)), u"tes"); + EXPECT_EQ(testu.sub(from_end(2), to_end), u"st"); + EXPECT_EQ(testu.sub(from_end(3), 2), u"es"); + EXPECT_EQ(testu.sub(from_end(3), from_end(1)), u"es"); + EXPECT_EQ(testu.str_mid(1), u"est"); EXPECT_EQ(testu.str_mid(1, 0), u""); EXPECT_EQ(testu.str_mid(1, 2), u"es"); EXPECT_EQ(testu.str_mid(2, 2), u"st"); ssw testw = L"test"; +#if 0 EXPECT_EQ(testw.substr(1, 0), L"est"); EXPECT_EQ(testw.substr(1, 2), L"es"); EXPECT_EQ(testw.substr(0, -1), L"tes"); EXPECT_EQ(testw.substr(-2), L"st"); EXPECT_EQ(testw.substr(-3, 2), L"es"); EXPECT_EQ(testw.substr(-3, -1), L"es"); +#endif + EXPECT_EQ(testw.sub(1, to_end), L"est"); + EXPECT_EQ(testw.sub(1, 2), L"es"); + EXPECT_EQ(testw.sub(0, from_end(1)), L"tes"); + EXPECT_EQ(testw.sub(from_end(2), to_end), L"st"); + EXPECT_EQ(testw.sub(from_end(3), 2), L"es"); + EXPECT_EQ(testw.sub(from_end(3), from_end(1)), L"es"); + EXPECT_EQ(testw.str_mid(1), L"est"); EXPECT_EQ(testw.str_mid(1, 0), L""); EXPECT_EQ(testw.str_mid(1, 2), L"es"); @@ -330,7 +375,7 @@ TEST(SimStr, SimpleSubstr) { TEST(SimStr, ToInt) { EXPECT_EQ(ssa{" 123"}.as_int(), 123); - EXPECT_EQ(ssa{" 123"}(0, -1).as_int(), 12); + EXPECT_EQ(ssa{" 123"}.get(0, from_end(1)).as_int(), 12); EXPECT_EQ(ssa{"+123"}.as_int(), 123); EXPECT_EQ(ssa{" -123aa"}.as_int(), -123); EXPECT_EQ(ssa{"123"}.as_int(), 123u); @@ -813,7 +858,7 @@ TEST(SimStr, AssignSstring) { EXPECT_EQ(test = ssa{"other"}, "other"); EXPECT_EQ(test = stringa{"trtr"_ss + 10}, "trtr10"); EXPECT_EQ(test = "trtr"_ss + 20, "trtr20"); - EXPECT_EQ(test = test(2), "tr20"); + EXPECT_EQ(test = test.get(2, to_end), "tr20"); EXPECT_EQ(test = lstringa<10>{"func"}, "func"); EXPECT_EQ(test = lstringsa<10>{"func"}, "func"); lstringsa<10> sample{15, "1234"}; @@ -942,10 +987,10 @@ TEST(SimStr, LStringAssign) { test = lstringa<1>{"next step"}; EXPECT_EQ(test, "next step"); - test = test(0); + test = test.get(0, to_end); EXPECT_EQ(test, "next step"); - test = test(1, 2); + test = test.get(1, 2); EXPECT_EQ(test, "ex"); test = e_c(100, 'a'); @@ -1405,7 +1450,7 @@ TEST(SimStr, LStrJoinAndExpressions) { buffer.prepend(e_choice(test.length() > 2, eea + 99, eea + 12.1 + "asd")); EXPECT_EQ(buffer, "99asd<>fgh<>jkl"); - buffer.change(2, 4, test(0, 3) + "__" + 1 + ','); + buffer.change(2, 4, test.get(0, 3) + "__" + 1 + ','); EXPECT_EQ(buffer, "99>as__1,>fgh<>jkl"); } diff --git a/tests/test_tostrexpr.cpp b/tests/test_tostrexpr.cpp index 441cfa1..c125a98 100644 --- a/tests/test_tostrexpr.cpp +++ b/tests/test_tostrexpr.cpp @@ -1,5 +1,5 @@ /* - * ver. 1.8.2 + * ver. 1.9.1 * (c) Проект "SimStr", Александр Орефков orefkov@gmail.com * Тесты simstr * (c) Project "SimStr", Aleksandr Orefkov orefkov@gmail.com