diff options
author | yazevnul <yazevnul@yandex-team.ru> | 2022-02-10 16:46:48 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:48 +0300 |
commit | 9abfb1a53b7f7b791444d1378e645d8fad9b06ed (patch) | |
tree | 49e222ea1c5804306084bb3ae065bb702625360f /util/string | |
parent | 8cbc307de0221f84c80c42dcbe07d40727537e2c (diff) | |
download | ydb-9abfb1a53b7f7b791444d1378e645d8fad9b06ed.tar.gz |
Restoring authorship annotation for <yazevnul@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'util/string')
38 files changed, 1195 insertions, 1195 deletions
diff --git a/util/string/ascii.h b/util/string/ascii.h index 9c2c090df1..10344384d3 100644 --- a/util/string/ascii.h +++ b/util/string/ascii.h @@ -60,7 +60,7 @@ namespace NPrivate { #endif } -constexpr bool IsAscii(const int c) noexcept { +constexpr bool IsAscii(const int c) noexcept { return !(c & ~0x7f); } diff --git a/util/string/ascii_ut.cpp b/util/string/ascii_ut.cpp index 94fea01a0e..89069fee50 100644 --- a/util/string/ascii_ut.cpp +++ b/util/string/ascii_ut.cpp @@ -3,8 +3,8 @@ #include <library/cpp/testing/unittest/registar.h> -Y_UNIT_TEST_SUITE(TAsciiTest) { - Y_UNIT_TEST(TestAscii) { +Y_UNIT_TEST_SUITE(TAsciiTest) { + Y_UNIT_TEST(TestAscii) { UNIT_ASSERT(IsAsciiDigit('3')); UNIT_ASSERT(!IsAsciiDigit('x')); @@ -38,7 +38,7 @@ Y_UNIT_TEST_SUITE(TAsciiTest) { } } - Y_UNIT_TEST(Test1) { + Y_UNIT_TEST(Test1) { for (int i = 128; i < 1000; ++i) { UNIT_ASSERT(!IsAsciiHex(i)); UNIT_ASSERT(!IsAsciiSpace(i)); @@ -62,7 +62,7 @@ Y_UNIT_TEST_SUITE(TAsciiTest) { } } - Y_UNIT_TEST(CompareTest) { + Y_UNIT_TEST(CompareTest) { UNIT_ASSERT(AsciiEqualsIgnoreCase("qqq", "qQq")); UNIT_ASSERT(AsciiEqualsIgnoreCase("qqq", TStringBuf("qQq"))); TString qq = "qq"; diff --git a/util/string/benchmark/float_to_string/main.cpp b/util/string/benchmark/float_to_string/main.cpp index c15b6009ad..1c7c0684a3 100644 --- a/util/string/benchmark/float_to_string/main.cpp +++ b/util/string/benchmark/float_to_string/main.cpp @@ -1,253 +1,253 @@ #include <library/cpp/testing/benchmark/bench.h> - -#include <util/generic/singleton.h> -#include <util/generic/vector.h> -#include <util/generic/xrange.h> -#include <util/generic/ymath.h> -#include <util/random/fast.h> -#include <util/string/cast.h> -#include <util/string/printf.h> - -#include <limits> - -#include <cmath> - -/* Please be careful before making any decisions based on this benchmark. - * - * Only `Sprintf("%.<decimals>f", x)` and `FloatToString(x, PREC_POINT_DIGITS, decimals` produce - * equal results in general case. However, results for cases when x \in [0, 1) must be equal for - * both `Sprintf` and `FloatToString`. - * - * Read more about formatting in STL [1, 2] and Yandex Util formatting [3] - * - * [1] http://www.cplusplus.com/reference/cstdio/printf/ - * [2] http://en.cppreference.com/w/c/io/fprintf - * [3] https://a.yandex-team.ru/arc/trunk/arcadia/util/string/cast.h?rev=2432660#L29 - */ - -namespace { - template <typename T> - struct TExample { - T Value{}; - int DigitsCount{}; - }; - - template <typename T, size_t N> - struct TExamplesHolder { + +#include <util/generic/singleton.h> +#include <util/generic/vector.h> +#include <util/generic/xrange.h> +#include <util/generic/ymath.h> +#include <util/random/fast.h> +#include <util/string/cast.h> +#include <util/string/printf.h> + +#include <limits> + +#include <cmath> + +/* Please be careful before making any decisions based on this benchmark. + * + * Only `Sprintf("%.<decimals>f", x)` and `FloatToString(x, PREC_POINT_DIGITS, decimals` produce + * equal results in general case. However, results for cases when x \in [0, 1) must be equal for + * both `Sprintf` and `FloatToString`. + * + * Read more about formatting in STL [1, 2] and Yandex Util formatting [3] + * + * [1] http://www.cplusplus.com/reference/cstdio/printf/ + * [2] http://en.cppreference.com/w/c/io/fprintf + * [3] https://a.yandex-team.ru/arc/trunk/arcadia/util/string/cast.h?rev=2432660#L29 + */ + +namespace { + template <typename T> + struct TExample { + T Value{}; + int DigitsCount{}; + }; + + template <typename T, size_t N> + struct TExamplesHolder { TVector<TExample<T>> Examples; - - TExamplesHolder() + + TExamplesHolder() : Examples(N) { - TFastRng<ui64> prng{N * sizeof(T) * 42}; - for (auto& x : Examples) { - x.Value = prng.GenRandReal4() + prng.Uniform(Max<ui16>()); - x.DigitsCount = prng.Uniform(std::numeric_limits<T>::max_digits10 + 1); - } - } - }; - - template <typename T, size_t N> - struct TNearZeroExamplesHolder { + TFastRng<ui64> prng{N * sizeof(T) * 42}; + for (auto& x : Examples) { + x.Value = prng.GenRandReal4() + prng.Uniform(Max<ui16>()); + x.DigitsCount = prng.Uniform(std::numeric_limits<T>::max_digits10 + 1); + } + } + }; + + template <typename T, size_t N> + struct TNearZeroExamplesHolder { TVector<TExample<T>> Examples; - - TNearZeroExamplesHolder() + + TNearZeroExamplesHolder() : Examples(N) { - TFastRng<ui64> prng{N * sizeof(T) * 42}; - for (auto& x : Examples) { - x.Value = prng.GenRandReal4(); - x.DigitsCount = prng.Uniform(std::numeric_limits<T>::max_digits10 + 1); - } - } - }; -} - -static const char* FORMAT_FIXED[] = { - "%.0f", - "%.1f", - "%.2f", - "%.3f", - "%.4f", - "%.5f", - "%.6f", - "%.7f", - "%.8f", - "%.9f", - "%.10f", - "%.11f", - "%.12f", - "%.13f", - "%.14f", - "%.15f", - "%.16f", - "%.17f", -}; - -static const char* FORMAT_SIGNIFICANT[] = { - "%.0g", - "%.1g", - "%.2g", - "%.3g", - "%.4g", - "%.5g", - "%.6g", - "%.7g", - "%.8g", - "%.9g", - "%.10g", - "%.11g", - "%.12g", - "%.13g", - "%.14g", - "%.15g", - "%.16g", - "%.17g", -}; - -#define DEFINE_BENCHMARK(type, count) \ - Y_CPU_BENCHMARK(SprintfAuto_##type##_##count, iface) { \ - const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ - for (const auto i : xrange(iface.Iterations())) { \ - Y_UNUSED(i); \ - for (const auto e : examples) { \ - /* this is in fact equal to Sprintf("%.6f", e.Value) and that is why it is faster */ \ - /* than FloatToString(e.Value) */ \ - Y_DO_NOT_OPTIMIZE_AWAY(Sprintf("%f", e.Value)); \ - } \ - } \ - } \ - \ - Y_CPU_BENCHMARK(FloatToStringAuto_##type##_##count, iface) { \ - const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ - for (const auto i : xrange(iface.Iterations())) { \ - Y_UNUSED(i); \ - for (const auto e : examples) { \ - Y_DO_NOT_OPTIMIZE_AWAY(FloatToString(e.Value)); \ - } \ - } \ - } \ - \ - Y_CPU_BENCHMARK(SprintfFixed_##type##_##count, iface) { \ - const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ - for (const auto i : xrange(iface.Iterations())) { \ - Y_UNUSED(i); \ - for (const auto e : examples) { \ - Y_DO_NOT_OPTIMIZE_AWAY(Sprintf(FORMAT_FIXED[e.DigitsCount], e.Value)); \ - } \ - } \ - } \ - \ - Y_CPU_BENCHMARK(FloatToStringFixed_##type##_##count, iface) { \ - const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ - for (const auto i : xrange(iface.Iterations())) { \ - Y_UNUSED(i); \ - for (const auto e : examples) { \ - Y_DO_NOT_OPTIMIZE_AWAY(FloatToString(e.Value, PREC_NDIGITS, e.DigitsCount)); \ - } \ - } \ - } \ - \ - Y_CPU_BENCHMARK(SprintfSignificant_##type##_##count, iface) { \ - const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ - for (const auto i : xrange(iface.Iterations())) { \ - Y_UNUSED(i); \ - for (const auto e : examples) { \ - Y_DO_NOT_OPTIMIZE_AWAY(Sprintf(FORMAT_SIGNIFICANT[e.DigitsCount], e.Value)); \ - } \ - } \ - } \ - \ - Y_CPU_BENCHMARK(FloatToStringSignificant_##type##_##count, iface) { \ - const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ - for (const auto i : xrange(iface.Iterations())) { \ - Y_UNUSED(i); \ - for (const auto e : examples) { \ - Y_DO_NOT_OPTIMIZE_AWAY(FloatToString(e.Value, PREC_POINT_DIGITS, e.DigitsCount)); \ - } \ - } \ - } \ - \ - Y_CPU_BENCHMARK(NearZeroSprintfAuto_##type##_##count, iface) { \ - const auto& examples = Default<TNearZeroExamplesHolder<type, count>>().Examples; \ - for (const auto i : xrange(iface.Iterations())) { \ - Y_UNUSED(i); \ - for (const auto e : examples) { \ - /* this is in fact equal to Sprintf("%.6f", e.Value) and that is why it is faster */ \ - /* than FloatToString(e.Value) */ \ - Y_DO_NOT_OPTIMIZE_AWAY(Sprintf("%f", e.Value)); \ - } \ - } \ - } \ - \ - Y_CPU_BENCHMARK(NearZeroFloatToStringAuto_##type##_##count, iface) { \ - const auto& examples = Default<TNearZeroExamplesHolder<type, count>>().Examples; \ - for (const auto i : xrange(iface.Iterations())) { \ - Y_UNUSED(i); \ - for (const auto e : examples) { \ - Y_DO_NOT_OPTIMIZE_AWAY(FloatToString(e.Value)); \ - } \ - } \ - } \ - \ - Y_CPU_BENCHMARK(NearZeroSprintfFixed_##type##_##count, iface) { \ - const auto& examples = Default<TNearZeroExamplesHolder<type, count>>().Examples; \ - for (const auto i : xrange(iface.Iterations())) { \ - Y_UNUSED(i); \ - for (const auto e : examples) { \ - Y_DO_NOT_OPTIMIZE_AWAY(Sprintf(FORMAT_FIXED[e.DigitsCount], e.Value)); \ - } \ - } \ - } \ - \ - Y_CPU_BENCHMARK(NearZeroFloatToStringFixed_##type##_##count, iface) { \ - const auto& examples = Default<TNearZeroExamplesHolder<type, count>>().Examples; \ - for (const auto i : xrange(iface.Iterations())) { \ - Y_UNUSED(i); \ - for (const auto e : examples) { \ - Y_DO_NOT_OPTIMIZE_AWAY(FloatToString(e.Value, PREC_NDIGITS, e.DigitsCount)); \ - } \ - } \ - } \ - \ - Y_CPU_BENCHMARK(NearZeroSprintfSignificant_##type##_##count, iface) { \ - const auto& examples = Default<TNearZeroExamplesHolder<type, count>>().Examples; \ - for (const auto i : xrange(iface.Iterations())) { \ - Y_UNUSED(i); \ - for (const auto e : examples) { \ - Y_DO_NOT_OPTIMIZE_AWAY(Sprintf(FORMAT_SIGNIFICANT[e.DigitsCount], e.Value)); \ - } \ - } \ - } \ - \ - Y_CPU_BENCHMARK(NearZeroFloatToStringSignificant_##type##_##count, iface) { \ - const auto& examples = Default<TNearZeroExamplesHolder<type, count>>().Examples; \ - for (const auto i : xrange(iface.Iterations())) { \ - Y_UNUSED(i); \ - for (const auto e : examples) { \ - Y_DO_NOT_OPTIMIZE_AWAY(FloatToString(e.Value, PREC_POINT_DIGITS, e.DigitsCount)); \ - } \ - } \ - } - -DEFINE_BENCHMARK(float, 1); -DEFINE_BENCHMARK(float, 2); -DEFINE_BENCHMARK(float, 4); -DEFINE_BENCHMARK(float, 8); -DEFINE_BENCHMARK(float, 16); -DEFINE_BENCHMARK(float, 32); -DEFINE_BENCHMARK(float, 64); -DEFINE_BENCHMARK(float, 128); -DEFINE_BENCHMARK(float, 256); - -DEFINE_BENCHMARK(double, 1); -DEFINE_BENCHMARK(double, 2); -DEFINE_BENCHMARK(double, 4); -DEFINE_BENCHMARK(double, 8); -DEFINE_BENCHMARK(double, 16); -DEFINE_BENCHMARK(double, 32); -DEFINE_BENCHMARK(double, 64); -DEFINE_BENCHMARK(double, 128); -DEFINE_BENCHMARK(double, 256); - -#undef DEFINE_BENCHMARK + TFastRng<ui64> prng{N * sizeof(T) * 42}; + for (auto& x : Examples) { + x.Value = prng.GenRandReal4(); + x.DigitsCount = prng.Uniform(std::numeric_limits<T>::max_digits10 + 1); + } + } + }; +} + +static const char* FORMAT_FIXED[] = { + "%.0f", + "%.1f", + "%.2f", + "%.3f", + "%.4f", + "%.5f", + "%.6f", + "%.7f", + "%.8f", + "%.9f", + "%.10f", + "%.11f", + "%.12f", + "%.13f", + "%.14f", + "%.15f", + "%.16f", + "%.17f", +}; + +static const char* FORMAT_SIGNIFICANT[] = { + "%.0g", + "%.1g", + "%.2g", + "%.3g", + "%.4g", + "%.5g", + "%.6g", + "%.7g", + "%.8g", + "%.9g", + "%.10g", + "%.11g", + "%.12g", + "%.13g", + "%.14g", + "%.15g", + "%.16g", + "%.17g", +}; + +#define DEFINE_BENCHMARK(type, count) \ + Y_CPU_BENCHMARK(SprintfAuto_##type##_##count, iface) { \ + const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + /* this is in fact equal to Sprintf("%.6f", e.Value) and that is why it is faster */ \ + /* than FloatToString(e.Value) */ \ + Y_DO_NOT_OPTIMIZE_AWAY(Sprintf("%f", e.Value)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(FloatToStringAuto_##type##_##count, iface) { \ + const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(FloatToString(e.Value)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(SprintfFixed_##type##_##count, iface) { \ + const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(Sprintf(FORMAT_FIXED[e.DigitsCount], e.Value)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(FloatToStringFixed_##type##_##count, iface) { \ + const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(FloatToString(e.Value, PREC_NDIGITS, e.DigitsCount)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(SprintfSignificant_##type##_##count, iface) { \ + const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(Sprintf(FORMAT_SIGNIFICANT[e.DigitsCount], e.Value)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(FloatToStringSignificant_##type##_##count, iface) { \ + const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(FloatToString(e.Value, PREC_POINT_DIGITS, e.DigitsCount)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(NearZeroSprintfAuto_##type##_##count, iface) { \ + const auto& examples = Default<TNearZeroExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + /* this is in fact equal to Sprintf("%.6f", e.Value) and that is why it is faster */ \ + /* than FloatToString(e.Value) */ \ + Y_DO_NOT_OPTIMIZE_AWAY(Sprintf("%f", e.Value)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(NearZeroFloatToStringAuto_##type##_##count, iface) { \ + const auto& examples = Default<TNearZeroExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(FloatToString(e.Value)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(NearZeroSprintfFixed_##type##_##count, iface) { \ + const auto& examples = Default<TNearZeroExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(Sprintf(FORMAT_FIXED[e.DigitsCount], e.Value)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(NearZeroFloatToStringFixed_##type##_##count, iface) { \ + const auto& examples = Default<TNearZeroExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(FloatToString(e.Value, PREC_NDIGITS, e.DigitsCount)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(NearZeroSprintfSignificant_##type##_##count, iface) { \ + const auto& examples = Default<TNearZeroExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(Sprintf(FORMAT_SIGNIFICANT[e.DigitsCount], e.Value)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(NearZeroFloatToStringSignificant_##type##_##count, iface) { \ + const auto& examples = Default<TNearZeroExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(FloatToString(e.Value, PREC_POINT_DIGITS, e.DigitsCount)); \ + } \ + } \ + } + +DEFINE_BENCHMARK(float, 1); +DEFINE_BENCHMARK(float, 2); +DEFINE_BENCHMARK(float, 4); +DEFINE_BENCHMARK(float, 8); +DEFINE_BENCHMARK(float, 16); +DEFINE_BENCHMARK(float, 32); +DEFINE_BENCHMARK(float, 64); +DEFINE_BENCHMARK(float, 128); +DEFINE_BENCHMARK(float, 256); + +DEFINE_BENCHMARK(double, 1); +DEFINE_BENCHMARK(double, 2); +DEFINE_BENCHMARK(double, 4); +DEFINE_BENCHMARK(double, 8); +DEFINE_BENCHMARK(double, 16); +DEFINE_BENCHMARK(double, 32); +DEFINE_BENCHMARK(double, 64); +DEFINE_BENCHMARK(double, 128); +DEFINE_BENCHMARK(double, 256); + +#undef DEFINE_BENCHMARK diff --git a/util/string/benchmark/float_to_string/metrics/main.py b/util/string/benchmark/float_to_string/metrics/main.py index fdcfd71b0b..e9d4b7ac1d 100644 --- a/util/string/benchmark/float_to_string/metrics/main.py +++ b/util/string/benchmark/float_to_string/metrics/main.py @@ -1,5 +1,5 @@ -import yatest.common as yc - - -def test_export_metrics(metrics): +import yatest.common as yc + + +def test_export_metrics(metrics): metrics.set_benchmark(yc.execute_benchmark('util/string/benchmark/float_to_string/float_to_string', threads=8)) diff --git a/util/string/benchmark/float_to_string/metrics/ya.make b/util/string/benchmark/float_to_string/metrics/ya.make index 3081301d1d..4b8c4cc07d 100644 --- a/util/string/benchmark/float_to_string/metrics/ya.make +++ b/util/string/benchmark/float_to_string/metrics/ya.make @@ -1,21 +1,21 @@ -OWNER( - yazevnul +OWNER( + yazevnul g:util -) +) SUBSCRIBER(g:util-subscribers) - + PY2TEST() - + SIZE(LARGE) - -TAG( + +TAG( ya:force_sandbox - sb:intel_e5_2660v1 + sb:intel_e5_2660v1 ya:fat -) - +) + TEST_SRCS(main.py) - + DEPENDS(util/string/benchmark/float_to_string) - -END() + +END() diff --git a/util/string/benchmark/float_to_string/ya.make b/util/string/benchmark/float_to_string/ya.make index 30955f3189..8136ad34f0 100644 --- a/util/string/benchmark/float_to_string/ya.make +++ b/util/string/benchmark/float_to_string/ya.make @@ -1,12 +1,12 @@ OWNER(yazevnul) - + Y_BENCHMARK() - + # to minimize allocations overhead ALLOCATOR(B) - -SRCS( - main.cpp -) - -END() + +SRCS( + main.cpp +) + +END() diff --git a/util/string/benchmark/subst_global/main.cpp b/util/string/benchmark/subst_global/main.cpp index c9b14a5211..e0decfa042 100644 --- a/util/string/benchmark/subst_global/main.cpp +++ b/util/string/benchmark/subst_global/main.cpp @@ -1,203 +1,203 @@ #include <library/cpp/testing/benchmark/bench.h> - -#include <util/generic/cast.h> -#include <util/generic/singleton.h> + +#include <util/generic/cast.h> +#include <util/generic/singleton.h> #include <util/generic/string.h> -#include <util/generic/xrange.h> -#include <util/random/fast.h> -#include <util/string/cast.h> -#include <util/string/subst.h> - -namespace { - template <size_t N, char What, char With> - struct TNoMatches { - enum : char { - WHAT = What, - WITH = With - }; +#include <util/generic/xrange.h> +#include <util/random/fast.h> +#include <util/string/cast.h> +#include <util/string/subst.h> + +namespace { + template <size_t N, char What, char With> + struct TNoMatches { + enum : char { + WHAT = What, + WITH = With + }; TString Str; - - TNoMatches() { - for (const auto dummy : xrange(N)) { - Y_UNUSED(dummy); - Str += WHAT + 1; - } - } - }; - - template <size_t N, char What, char With> - struct TOneMatchInTheBeginning { - enum : char { - WHAT = What, - WITH = With - }; + + TNoMatches() { + for (const auto dummy : xrange(N)) { + Y_UNUSED(dummy); + Str += WHAT + 1; + } + } + }; + + template <size_t N, char What, char With> + struct TOneMatchInTheBeginning { + enum : char { + WHAT = What, + WITH = With + }; TString Str; - - TOneMatchInTheBeginning() { - if (!N) { - return; - } - - Str += WHAT; - if (N > 1) { - for (const auto dummy : xrange(N - 1)) { - Y_UNUSED(dummy); - Str += WHAT + 1; - } - } - } - }; - - template <size_t N, char What, char With> - struct TOneMatchInTheEnd { - enum : char { - WHAT = What, - WITH = With - }; + + TOneMatchInTheBeginning() { + if (!N) { + return; + } + + Str += WHAT; + if (N > 1) { + for (const auto dummy : xrange(N - 1)) { + Y_UNUSED(dummy); + Str += WHAT + 1; + } + } + } + }; + + template <size_t N, char What, char With> + struct TOneMatchInTheEnd { + enum : char { + WHAT = What, + WITH = With + }; TString Str; - - TOneMatchInTheEnd() { - if (!N) { - return; - } - - if (N > 1) { - for (const auto dummy : xrange(N - 1)) { - Y_UNUSED(dummy); - Str += WHAT + 1; - } - } - Str += WHAT; - } - }; - - template <size_t N, char What, char With> - struct TOneMatchInTheMiddle { - enum : char { - WHAT = What, - WITH = With - }; + + TOneMatchInTheEnd() { + if (!N) { + return; + } + + if (N > 1) { + for (const auto dummy : xrange(N - 1)) { + Y_UNUSED(dummy); + Str += WHAT + 1; + } + } + Str += WHAT; + } + }; + + template <size_t N, char What, char With> + struct TOneMatchInTheMiddle { + enum : char { + WHAT = What, + WITH = With + }; TString Str; - - TOneMatchInTheMiddle() { - if (!N) { - return; - } - - for (size_t i = 0; i < N / 2; ++i) { - Str += WHAT + 1; - } - Str += WHAT; - for (; Str.size() < N;) { - Str += WHAT + 1; - } - } - }; - - template <size_t N, char What, char With> - struct TFirstHalfMatches { - enum : char { - WHAT = What, - WITH = With - }; + + TOneMatchInTheMiddle() { + if (!N) { + return; + } + + for (size_t i = 0; i < N / 2; ++i) { + Str += WHAT + 1; + } + Str += WHAT; + for (; Str.size() < N;) { + Str += WHAT + 1; + } + } + }; + + template <size_t N, char What, char With> + struct TFirstHalfMatches { + enum : char { + WHAT = What, + WITH = With + }; TString Str; - - TFirstHalfMatches() { - for (size_t i = 0; i < N / 2; ++i) { - Str += WHAT; - } - for (; Str.size() != N;) { - Str += WHAT + 1; - } - } - }; - - template <size_t N, char What, char With> - struct TSecondHalfMatches { - enum : char { - WHAT = What, - WITH = With - }; + + TFirstHalfMatches() { + for (size_t i = 0; i < N / 2; ++i) { + Str += WHAT; + } + for (; Str.size() != N;) { + Str += WHAT + 1; + } + } + }; + + template <size_t N, char What, char With> + struct TSecondHalfMatches { + enum : char { + WHAT = What, + WITH = With + }; TString Str; - - TSecondHalfMatches() { - for (size_t i = 0; i < N / 2; ++i) { - Str += WHAT + 1; - } - for (; Str.size() != N;) { - Str += WHAT; - } - } - }; - - template <size_t N, size_t K, char What, char With> - struct TEveryKth { - enum : char { - WHAT = What, - WITH = With - }; + + TSecondHalfMatches() { + for (size_t i = 0; i < N / 2; ++i) { + Str += WHAT + 1; + } + for (; Str.size() != N;) { + Str += WHAT; + } + } + }; + + template <size_t N, size_t K, char What, char With> + struct TEveryKth { + enum : char { + WHAT = What, + WITH = With + }; TString Str; - - TEveryKth() { - TFastRng<ui64> prng{N * K * 101}; - for (size_t i = 0; i < N; ++i) { - Str += (prng() % K) ? (WHAT + 1) : WHAT; - } - } - }; -} - -#define DEFINE_BENCHMARK(type, N) \ - Y_CPU_BENCHMARK(type##_##N, i) { \ - using D = T##type<N, 'a', 'z'>; \ - const auto& str = Default<D>().Str; \ - for (const auto dummy : xrange(i.Iterations())) { \ - Y_UNUSED(dummy); \ - auto s = str; \ + + TEveryKth() { + TFastRng<ui64> prng{N * K * 101}; + for (size_t i = 0; i < N; ++i) { + Str += (prng() % K) ? (WHAT + 1) : WHAT; + } + } + }; +} + +#define DEFINE_BENCHMARK(type, N) \ + Y_CPU_BENCHMARK(type##_##N, i) { \ + using D = T##type<N, 'a', 'z'>; \ + const auto& str = Default<D>().Str; \ + for (const auto dummy : xrange(i.Iterations())) { \ + Y_UNUSED(dummy); \ + auto s = str; \ NBench::Escape(s.data()); \ - Y_DO_NOT_OPTIMIZE_AWAY(SubstGlobal(s, ToUnderlying(D::WHAT), ToUnderlying(D::WITH))); \ - NBench::Clobber(); \ - } \ - } - -#define DEFINE_RNG_BENCHMARK(N, K) \ - Y_CPU_BENCHMARK(Random_##N##_##K, i) { \ - using D = TEveryKth<N, K, 'a', 'z'>; \ - const auto& str = Default<D>().Str; \ - for (const auto dummy : xrange(i.Iterations())) { \ - Y_UNUSED(dummy); \ - auto s = str; \ + Y_DO_NOT_OPTIMIZE_AWAY(SubstGlobal(s, ToUnderlying(D::WHAT), ToUnderlying(D::WITH))); \ + NBench::Clobber(); \ + } \ + } + +#define DEFINE_RNG_BENCHMARK(N, K) \ + Y_CPU_BENCHMARK(Random_##N##_##K, i) { \ + using D = TEveryKth<N, K, 'a', 'z'>; \ + const auto& str = Default<D>().Str; \ + for (const auto dummy : xrange(i.Iterations())) { \ + Y_UNUSED(dummy); \ + auto s = str; \ NBench::Escape(s.data()); \ - Y_DO_NOT_OPTIMIZE_AWAY(SubstGlobal(s, ToUnderlying(D::WHAT), ToUnderlying(D::WITH))); \ - NBench::Clobber(); \ - } \ - } - -DEFINE_BENCHMARK(NoMatches, 0) -DEFINE_BENCHMARK(NoMatches, 1) -DEFINE_BENCHMARK(NoMatches, 128) -DEFINE_BENCHMARK(NoMatches, 4096) -DEFINE_BENCHMARK(OneMatchInTheBeginning, 1) -DEFINE_BENCHMARK(OneMatchInTheBeginning, 16) -DEFINE_BENCHMARK(OneMatchInTheBeginning, 128) -DEFINE_BENCHMARK(OneMatchInTheBeginning, 4096) -DEFINE_BENCHMARK(OneMatchInTheEnd, 16) -DEFINE_BENCHMARK(OneMatchInTheEnd, 128) -DEFINE_BENCHMARK(OneMatchInTheEnd, 4096) -DEFINE_BENCHMARK(OneMatchInTheMiddle, 16) -DEFINE_BENCHMARK(OneMatchInTheMiddle, 128) -DEFINE_BENCHMARK(OneMatchInTheMiddle, 4096) -DEFINE_BENCHMARK(FirstHalfMatches, 16) -DEFINE_BENCHMARK(FirstHalfMatches, 128) -DEFINE_BENCHMARK(FirstHalfMatches, 4096) -DEFINE_BENCHMARK(SecondHalfMatches, 16) -DEFINE_BENCHMARK(SecondHalfMatches, 128) -DEFINE_BENCHMARK(SecondHalfMatches, 4096) - -DEFINE_RNG_BENCHMARK(4096, 1) -DEFINE_RNG_BENCHMARK(4096, 2) -DEFINE_RNG_BENCHMARK(4096, 3) -DEFINE_RNG_BENCHMARK(4096, 4) -DEFINE_RNG_BENCHMARK(4096, 10) -DEFINE_RNG_BENCHMARK(4096, 32) -DEFINE_RNG_BENCHMARK(4096, 100) + Y_DO_NOT_OPTIMIZE_AWAY(SubstGlobal(s, ToUnderlying(D::WHAT), ToUnderlying(D::WITH))); \ + NBench::Clobber(); \ + } \ + } + +DEFINE_BENCHMARK(NoMatches, 0) +DEFINE_BENCHMARK(NoMatches, 1) +DEFINE_BENCHMARK(NoMatches, 128) +DEFINE_BENCHMARK(NoMatches, 4096) +DEFINE_BENCHMARK(OneMatchInTheBeginning, 1) +DEFINE_BENCHMARK(OneMatchInTheBeginning, 16) +DEFINE_BENCHMARK(OneMatchInTheBeginning, 128) +DEFINE_BENCHMARK(OneMatchInTheBeginning, 4096) +DEFINE_BENCHMARK(OneMatchInTheEnd, 16) +DEFINE_BENCHMARK(OneMatchInTheEnd, 128) +DEFINE_BENCHMARK(OneMatchInTheEnd, 4096) +DEFINE_BENCHMARK(OneMatchInTheMiddle, 16) +DEFINE_BENCHMARK(OneMatchInTheMiddle, 128) +DEFINE_BENCHMARK(OneMatchInTheMiddle, 4096) +DEFINE_BENCHMARK(FirstHalfMatches, 16) +DEFINE_BENCHMARK(FirstHalfMatches, 128) +DEFINE_BENCHMARK(FirstHalfMatches, 4096) +DEFINE_BENCHMARK(SecondHalfMatches, 16) +DEFINE_BENCHMARK(SecondHalfMatches, 128) +DEFINE_BENCHMARK(SecondHalfMatches, 4096) + +DEFINE_RNG_BENCHMARK(4096, 1) +DEFINE_RNG_BENCHMARK(4096, 2) +DEFINE_RNG_BENCHMARK(4096, 3) +DEFINE_RNG_BENCHMARK(4096, 4) +DEFINE_RNG_BENCHMARK(4096, 10) +DEFINE_RNG_BENCHMARK(4096, 32) +DEFINE_RNG_BENCHMARK(4096, 100) diff --git a/util/string/benchmark/subst_global/metrics/main.py b/util/string/benchmark/subst_global/metrics/main.py index 8aa0501351..62f2f3d76d 100644 --- a/util/string/benchmark/subst_global/metrics/main.py +++ b/util/string/benchmark/subst_global/metrics/main.py @@ -1,5 +1,5 @@ -import yatest.common as yc - - -def test_export_metrics(metrics): +import yatest.common as yc + + +def test_export_metrics(metrics): metrics.set_benchmark(yc.execute_benchmark('util/string/benchmark/subst_global/subst_global', threads=8)) diff --git a/util/string/benchmark/subst_global/metrics/ya.make b/util/string/benchmark/subst_global/metrics/ya.make index 73757bebcb..d8c30ad460 100644 --- a/util/string/benchmark/subst_global/metrics/ya.make +++ b/util/string/benchmark/subst_global/metrics/ya.make @@ -1,21 +1,21 @@ -OWNER( - yazevnul +OWNER( + yazevnul g:util -) +) SUBSCRIBER(g:util-subscribers) - + PY2TEST() - + SIZE(LARGE) - -TAG( + +TAG( ya:force_sandbox - sb:intel_e5_2660v1 + sb:intel_e5_2660v1 ya:fat -) - +) + TEST_SRCS(main.py) - + DEPENDS(util/string/benchmark/subst_global) - -END() + +END() diff --git a/util/string/benchmark/subst_global/ya.make b/util/string/benchmark/subst_global/ya.make index 30955f3189..8136ad34f0 100644 --- a/util/string/benchmark/subst_global/ya.make +++ b/util/string/benchmark/subst_global/ya.make @@ -1,12 +1,12 @@ OWNER(yazevnul) - + Y_BENCHMARK() - + # to minimize allocations overhead ALLOCATOR(B) - -SRCS( - main.cpp -) - -END() + +SRCS( + main.cpp +) + +END() diff --git a/util/string/benchmark/ya.make b/util/string/benchmark/ya.make index 09b112034d..266b53c7b3 100644 --- a/util/string/benchmark/ya.make +++ b/util/string/benchmark/ya.make @@ -1,16 +1,16 @@ -OWNER( +OWNER( g:util - yazevnul -) + yazevnul +) SUBSCRIBER(g:util-subscribers) - -RECURSE( + +RECURSE( ascii cast - float_to_string - float_to_string/metrics + float_to_string + float_to_string/metrics join join/metrics - subst_global - subst_global/metrics -) + subst_global + subst_global/metrics +) diff --git a/util/string/builder.cpp b/util/string/builder.cpp index e1f696c931..a3821d3399 100644 --- a/util/string/builder.cpp +++ b/util/string/builder.cpp @@ -3,6 +3,6 @@ #include <util/stream/output.h> template <> -void Out<TStringBuilder>(IOutputStream& os, const TStringBuilder& sb) { +void Out<TStringBuilder>(IOutputStream& os, const TStringBuilder& sb) { os << static_cast<const TString&>(sb); } diff --git a/util/string/builder_ut.cpp b/util/string/builder_ut.cpp index 49d1882266..22def683ec 100644 --- a/util/string/builder_ut.cpp +++ b/util/string/builder_ut.cpp @@ -17,19 +17,19 @@ struct TClassWithStreamOperator { } }; -IOutputStream& operator<<(IOutputStream& out, const TClassWithStreamOperator& value) { +IOutputStream& operator<<(IOutputStream& out, const TClassWithStreamOperator& value) { return out << value.Id << " " << value.Name; } -Y_UNIT_TEST_SUITE(TStringBuilderTest) { - Y_UNIT_TEST(TestStringBuilder) { +Y_UNIT_TEST_SUITE(TStringBuilderTest) { + Y_UNIT_TEST(TestStringBuilder) { TestEquals("", TStringBuilder()); TestEquals("a", TStringBuilder() << "a"); TestEquals("a1", TStringBuilder() << "a" << 1); TestEquals("value: 123 name", TStringBuilder() << "value: " << TClassWithStreamOperator(123, "name")); } - Y_UNIT_TEST(TestStringBuilderOut) { + Y_UNIT_TEST(TestStringBuilderOut) { TString s; TStringOutput out(s); TStringBuilder sb; @@ -38,7 +38,7 @@ Y_UNIT_TEST_SUITE(TStringBuilderTest) { TestEquals("a", s); } - Y_UNIT_TEST(TestStringBuilderRValue) { + Y_UNIT_TEST(TestStringBuilderRValue) { struct TRValueAcceptTester { static bool IsRValue(const TString&) { return false; diff --git a/util/string/cast.cpp b/util/string/cast.cpp index d1165cade1..aa1e65a8e9 100644 --- a/util/string/cast.cpp +++ b/util/string/cast.cpp @@ -30,123 +30,123 @@ using double_conversion::StringToDoubleConverter; * ------------------------------ formatters ------------------------------ */ -namespace { +namespace { constexpr char IntToChar[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - - static_assert(Y_ARRAY_SIZE(IntToChar) == 16, "expect Y_ARRAY_SIZE(IntToChar) == 16"); - + + static_assert(Y_ARRAY_SIZE(IntToChar) == 16, "expect Y_ARRAY_SIZE(IntToChar) == 16"); + // clang-format off constexpr int LetterToIntMap[] = { - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 0, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 20, 20, - 20, 20, 20, 20, 20, 10, 11, 12, 13, 14, - 15, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 10, 11, 12, - 13, 14, 15, - }; + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 20, 20, + 20, 20, 20, 20, 20, 10, 11, 12, 13, 14, + 15, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 10, 11, 12, + 13, 14, 15, + }; // clang-format on - - template <class T> + + template <class T> std::enable_if_t<std::is_signed<T>::value, std::make_unsigned_t<T>> NegateNegativeSigned(T value) noexcept { return std::make_unsigned_t<T>(-(value + 1)) + std::make_unsigned_t<T>(1); } - template <class T> + template <class T> std::enable_if_t<std::is_unsigned<T>::value, std::make_unsigned_t<T>> NegateNegativeSigned(T) noexcept { Y_UNREACHABLE(); - } + } template <class T> std::make_signed_t<T> NegatePositiveSigned(T value) noexcept { return value > 0 ? (-std::make_signed_t<T>(value - 1) - 1) : 0; } - template <class T, unsigned base, class TChar> - struct TBasicIntFormatter { - static_assert(1 < base && base < 17, "expect 1 < base && base < 17"); + template <class T, unsigned base, class TChar> + struct TBasicIntFormatter { + static_assert(1 < base && base < 17, "expect 1 < base && base < 17"); static_assert(std::is_unsigned<T>::value, "TBasicIntFormatter can only handle unsigned integers."); - static inline size_t Format(T value, TChar* buf, size_t len) { + static inline size_t Format(T value, TChar* buf, size_t len) { Y_ENSURE(len, TStringBuf("zero length")); - TChar* tmp = buf; - - do { + TChar* tmp = buf; + + do { // divide only once, do not use mod const T nextVal = static_cast<T>(value / base); *tmp++ = IntToChar[base == 2 || base == 4 || base == 8 || base == 16 ? value & (base - 1) : value - base * nextVal]; value = nextVal; - } while (value && --len); - + } while (value && --len); + Y_ENSURE(!value, TStringBuf("not enough room in buffer")); - - const size_t result = tmp - buf; - - --tmp; - - while (buf < tmp) { - TChar c = *buf; - - *buf = *tmp; - *tmp = c; - ++buf; - --tmp; - } - - return result; + + const size_t result = tmp - buf; + + --tmp; + + while (buf < tmp) { + TChar c = *buf; + + *buf = *tmp; + *tmp = c; + ++buf; + --tmp; + } + + return result; } - }; + }; - template <class T, unsigned base, class TChar> - struct TIntFormatter { - static_assert(1 < base && base < 17, "expect 1 < base && base < 17"); + template <class T, unsigned base, class TChar> + struct TIntFormatter { + static_assert(1 < base && base < 17, "expect 1 < base && base < 17"); static_assert(std::is_integral<T>::value, "T must be an integral type."); - static inline size_t Format(T value, TChar* buf, size_t len) { + static inline size_t Format(T value, TChar* buf, size_t len) { using TUFmt = TBasicIntFormatter<std::make_unsigned_t<T>, base, TChar>; - + if (std::is_signed<T>::value && value < 0) { Y_ENSURE(len >= 2, TStringBuf("not enough room in buffer")); - - *buf = '-'; + + *buf = '-'; return 1 + TUFmt::Format(NegateNegativeSigned(value), buf + 1, len - 1); - } - + } + return TUFmt::Format(value, buf, len); } - }; + }; - template <class T> - struct TFltModifiers; + template <class T> + struct TFltModifiers; - template <class T, int base, class TChar> + template <class T, int base, class TChar> Y_NO_INLINE size_t FormatInt(T value, TChar* buf, size_t len) { - return TIntFormatter<T, base, TChar>::Format(value, buf, len); - } + return TIntFormatter<T, base, TChar>::Format(value, buf, len); + } - template <class T> + template <class T> inline size_t FormatFlt(T t, char* buf, size_t len) { - const int ret = snprintf(buf, len, TFltModifiers<T>::ModifierWrite, t); + const int ret = snprintf(buf, len, TFltModifiers<T>::ModifierWrite, t); Y_ENSURE(ret >= 0 && (size_t)ret <= len, TStringBuf("cannot format float")); - return (size_t)ret; + return (size_t)ret; } - enum EParseStatus { - PS_OK = 0, - PS_EMPTY_STRING, - PS_PLUS_STRING, - PS_MINUS_STRING, - PS_BAD_SYMBOL, - PS_OVERFLOW, - }; + enum EParseStatus { + PS_OK = 0, + PS_EMPTY_STRING, + PS_PLUS_STRING, + PS_MINUS_STRING, + PS_BAD_SYMBOL, + PS_OVERFLOW, + }; constexpr ui8 SAFE_LENS[4][17] = { {0, 0, 7, 5, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1}, @@ -177,19 +177,19 @@ namespace { return (c >= '0') && ((*digit = (c - '0')) < BASE); } - template <class T, unsigned base, class TChar> - struct TBasicIntParser { - static_assert(1 < base && base < 17, "Expect 1 < base && base < 17."); + template <class T, unsigned base, class TChar> + struct TBasicIntParser { + static_assert(1 < base && base < 17, "Expect 1 < base && base < 17."); static_assert(std::is_unsigned<T>::value, "TBasicIntParser can only handle unsigned integers."); - + enum : unsigned { BASE_POW_2 = base * base, }; static inline EParseStatus Parse(const TChar** ppos, const TChar* end, T max, T* target) noexcept { - Y_ASSERT(*ppos != end); /* This check should be somewhere up the stack. */ + Y_ASSERT(*ppos != end); /* This check should be somewhere up the stack. */ const size_t maxSafeLen = SAFE_LENS[ConstLog2(sizeof(T))][base]; - + // can parse without overflow if (size_t(end - *ppos) <= maxSafeLen) { T result; @@ -205,7 +205,7 @@ namespace { } static inline bool ParseFast(const TChar* pos, const TChar* end, T* target) noexcept { - T result = T(); + T result = T(); T d1; T d2; @@ -229,164 +229,164 @@ namespace { static inline EParseStatus ParseSlow(const TChar** ppos, const TChar* end, T max, T* target) noexcept { T result = T(); - T preMulMax = max / base; - const TChar* pos = *ppos; - - while (pos != end) { - T digit; + T preMulMax = max / base; + const TChar* pos = *ppos; + + while (pos != end) { + T digit; if (!CharToDigit<base>(*pos, &digit)) { - *ppos = pos; - - return PS_BAD_SYMBOL; - } - - if (result > preMulMax) { - return PS_OVERFLOW; - } - - result *= base; - - if (result > max - digit) { - return PS_OVERFLOW; - } - - result += digit; - pos++; - } - - *target = result; - - return PS_OK; - } + *ppos = pos; + + return PS_BAD_SYMBOL; + } + + if (result > preMulMax) { + return PS_OVERFLOW; + } + + result *= base; + + if (result > max - digit) { + return PS_OVERFLOW; + } + + result += digit; + pos++; + } + + *target = result; + + return PS_OK; + } }; - template <class T> - struct TBounds { - T PositiveMax; - T NegativeMax; - }; + template <class T> + struct TBounds { + T PositiveMax; + T NegativeMax; + }; - template <class T, unsigned base, class TChar> - struct TIntParser { - static_assert(1 < base && base < 17, "Expect 1 < base && base < 17."); + template <class T, unsigned base, class TChar> + struct TIntParser { + static_assert(1 < base && base < 17, "Expect 1 < base && base < 17."); static_assert(std::is_integral<T>::value, "T must be an integral type."); - enum { + enum { IsSigned = std::is_signed<T>::value - }; - - using TUnsigned = std::make_unsigned_t<T>; - - static inline EParseStatus Parse(const TChar** ppos, const TChar* end, const TBounds<TUnsigned>& bounds, T* target) { - const TChar* pos = *ppos; - if (pos == end) { - return PS_EMPTY_STRING; + }; + + using TUnsigned = std::make_unsigned_t<T>; + + static inline EParseStatus Parse(const TChar** ppos, const TChar* end, const TBounds<TUnsigned>& bounds, T* target) { + const TChar* pos = *ppos; + if (pos == end) { + return PS_EMPTY_STRING; } bool negative = false; - TUnsigned max; - if (*pos == '+') { - pos++; - max = bounds.PositiveMax; - - if (pos == end) { - return PS_PLUS_STRING; - } - } else if (IsSigned && *pos == '-') { - pos++; - max = bounds.NegativeMax; - negative = true; - - if (pos == end) { - return PS_MINUS_STRING; - } - } else { - max = bounds.PositiveMax; - } - - TUnsigned result; - EParseStatus error = TBasicIntParser<TUnsigned, base, TChar>::Parse(&pos, end, max, &result); - if (error != PS_OK) { + TUnsigned max; + if (*pos == '+') { + pos++; + max = bounds.PositiveMax; + + if (pos == end) { + return PS_PLUS_STRING; + } + } else if (IsSigned && *pos == '-') { + pos++; + max = bounds.NegativeMax; + negative = true; + + if (pos == end) { + return PS_MINUS_STRING; + } + } else { + max = bounds.PositiveMax; + } + + TUnsigned result; + EParseStatus error = TBasicIntParser<TUnsigned, base, TChar>::Parse(&pos, end, max, &result); + if (error != PS_OK) { *ppos = pos; - return error; - } - - if (IsSigned) { + return error; + } + + if (IsSigned) { *target = negative ? NegatePositiveSigned(result) : static_cast<T>(result); - } else { - *target = result; - } - return PS_OK; + } else { + *target = result; + } + return PS_OK; } - }; + }; - template <class TChar> + template <class TChar> [[noreturn]] static Y_NO_INLINE void ThrowParseError(EParseStatus status, const TChar* data, size_t len, const TChar* pos) { - Y_ASSERT(status != PS_OK); - + Y_ASSERT(status != PS_OK); + typedef TBasicString<TChar> TStringType; - - switch (status) { - case PS_EMPTY_STRING: + + switch (status) { + case PS_EMPTY_STRING: ythrow TFromStringException() << TStringBuf("Cannot parse empty string as number. "); - case PS_PLUS_STRING: + case PS_PLUS_STRING: ythrow TFromStringException() << TStringBuf("Cannot parse string \"+\" as number. "); - case PS_MINUS_STRING: + case PS_MINUS_STRING: ythrow TFromStringException() << TStringBuf("Cannot parse string \"-\" as number. "); - case PS_BAD_SYMBOL: + case PS_BAD_SYMBOL: ythrow TFromStringException() << TStringBuf("Unexpected symbol \"") << EscapeC(*pos) << TStringBuf("\" at pos ") << (pos - data) << TStringBuf(" in string ") << TStringType(data, len).Quote() << TStringBuf(". "); - case PS_OVERFLOW: + case PS_OVERFLOW: ythrow TFromStringException() << TStringBuf("Integer overflow in string ") << TStringType(data, len).Quote() << TStringBuf(". "); - default: + default: ythrow yexception() << TStringBuf("Unknown error code in string converter. "); - } + } } - template <typename T, typename TUnsigned, int base, typename TChar> + template <typename T, typename TUnsigned, int base, typename TChar> Y_NO_INLINE T ParseInt(const TChar* data, size_t len, const TBounds<TUnsigned>& bounds) { - T result; - const TChar* pos = data; - EParseStatus status = TIntParser<T, base, TChar>::Parse(&pos, pos + len, bounds, &result); - - if (status == PS_OK) { - return result; - } else { - ThrowParseError(status, data, len, pos); - } - } - - template <typename T, typename TUnsigned, int base, typename TChar> + T result; + const TChar* pos = data; + EParseStatus status = TIntParser<T, base, TChar>::Parse(&pos, pos + len, bounds, &result); + + if (status == PS_OK) { + return result; + } else { + ThrowParseError(status, data, len, pos); + } + } + + template <typename T, typename TUnsigned, int base, typename TChar> Y_NO_INLINE bool TryParseInt(const TChar* data, size_t len, const TBounds<TUnsigned>& bounds, T* result) { - return TIntParser<T, base, TChar>::Parse(&data, data + len, bounds, result) == PS_OK; - } - - template <class T> + return TIntParser<T, base, TChar>::Parse(&data, data + len, bounds, result) == PS_OK; + } + + template <class T> inline T ParseFlt(const char* data, size_t len) { - /* - * TODO - */ - - if (len > 256) { - len = 256; - } - - char* c = (char*)alloca(len + 1); - memcpy(c, data, len); - c[len] = 0; - - T ret; - char ec; - - // try to read a value and an extra character in order to catch cases when - // the string start with a valid float but is followed by unexpected characters - if (sscanf(c, TFltModifiers<T>::ModifierReadAndChar, &ret, &ec) == 1) { - return ret; - } - + /* + * TODO + */ + + if (len > 256) { + len = 256; + } + + char* c = (char*)alloca(len + 1); + memcpy(c, data, len); + c[len] = 0; + + T ret; + char ec; + + // try to read a value and an extra character in order to catch cases when + // the string start with a valid float but is followed by unexpected characters + if (sscanf(c, TFltModifiers<T>::ModifierReadAndChar, &ret, &ec) == 1) { + return ret; + } + ythrow TFromStringException() << TStringBuf("cannot parse float(") << TStringBuf(data, len) << TStringBuf(")"); - } - + } + #define DEF_FLT_MOD(type, modifierWrite, modifierRead) \ template <> \ struct TFltModifiers<type> { \ @@ -397,14 +397,14 @@ namespace { const char* const TFltModifiers<type>::ModifierWrite = modifierWrite; \ const char* const TFltModifiers<type>::ModifierReadAndChar = modifierRead "%c"; - DEF_FLT_MOD(long double, "%.10Lg", "%Lg") + DEF_FLT_MOD(long double, "%.10Lg", "%Lg") #undef DEF_FLT_MOD - /* The following constants are initialized in terms of <climits> constants to make - * sure they go into binary as actual values and there is no associated - * initialization code. - * */ + /* The following constants are initialized in terms of <climits> constants to make + * sure they go into binary as actual values and there is no associated + * initialization code. + * */ constexpr TBounds<ui64> bSBounds = {static_cast<ui64>(SCHAR_MAX), static_cast<ui64>(UCHAR_MAX - SCHAR_MAX)}; constexpr TBounds<ui64> bUBounds = {static_cast<ui64>(UCHAR_MAX), 0}; constexpr TBounds<ui64> sSBounds = {static_cast<ui64>(SHRT_MAX), static_cast<ui64>(USHRT_MAX - SHRT_MAX)}; @@ -450,8 +450,8 @@ size_t ToStringImpl<char8_t>(char8_t value, char* buf, size_t len) { } #endif -using TCharIType = std::conditional_t<std::is_signed<char>::value, i64, ui64>; -using TWCharIType = std::conditional_t<std::is_signed<wchar_t>::value, i64, ui64>; +using TCharIType = std::conditional_t<std::is_signed<char>::value, i64, ui64>; +using TWCharIType = std::conditional_t<std::is_signed<wchar_t>::value, i64, ui64>; DEF_INT_SPEC_I(char, TCharIType) DEF_INT_SPEC_I(wchar_t, TWCharIType) @@ -472,13 +472,13 @@ DEF_FLT_SPEC(long double) #undef DEF_FLT_SPEC -template <> -size_t ToStringImpl<bool>(bool t, char* buf, size_t len) { +template <> +size_t ToStringImpl<bool>(bool t, char* buf, size_t len) { Y_ENSURE(len, TStringBuf("zero length")); - *buf = t ? '1' : '0'; - return 1; -} - + *buf = t ? '1' : '0'; + return 1; +} + /* * ------------------------------ parsers ------------------------------ */ @@ -543,12 +543,12 @@ TWtringBuf FromStringImpl<TWtringBuf>(const wchar16* data, size_t len) { // Try-versions template <> -bool TryFromStringImpl<TStringBuf>(const char* data, size_t len, TStringBuf& result) { - result = {data, len}; - return true; -} - -template <> +bool TryFromStringImpl<TStringBuf>(const char* data, size_t len, TStringBuf& result) { + result = {data, len}; + return true; +} + +template <> bool TryFromStringImpl<TString>(const char* data, size_t len, TString& result) { result = TString(data, len); return true; @@ -561,12 +561,12 @@ bool TryFromStringImpl<std::string>(const char* data, size_t len, std::string& r } template <> -bool TryFromStringImpl<TWtringBuf>(const wchar16* data, size_t len, TWtringBuf& result) { - result = {data, len}; - return true; -} - -template <> +bool TryFromStringImpl<TWtringBuf>(const wchar16* data, size_t len, TWtringBuf& result) { + result = {data, len}; + return true; +} + +template <> bool TryFromStringImpl<TUtf16String>(const wchar16* data, size_t len, TUtf16String& result) { result = TUtf16String(data, len); return true; @@ -648,7 +648,7 @@ bool TryFromStringImpl<double>(const char* data, size_t len, double& result) { return false; } - char* se = nullptr; + char* se = nullptr; double d = StrToD(data, data + len, &se); if (se != data + len) { diff --git a/util/string/cast_ut.cpp b/util/string/cast_ut.cpp index e6fec11e2c..033450c38c 100644 --- a/util/string/cast_ut.cpp +++ b/util/string/cast_ut.cpp @@ -149,7 +149,7 @@ inline void CheckConvertToBuffer(const T& value, const size_t size, const TStrin } #endif -Y_UNIT_TEST_SUITE(TCastTest) { +Y_UNIT_TEST_SUITE(TCastTest) { template <class A> inline TRet<A> F() { return TRet<A>(); @@ -173,10 +173,10 @@ Y_UNIT_TEST_SUITE(TCastTest) { UNIT_ASSERT_VALUES_EQUAL(res, false); UNIT_ASSERT_DOUBLES_EQUAL(f, 42.0, eps); // check value was not trashed UNIT_ASSERT_EXCEPTION(f = FromString<TFloat>(str), TFromStringException); - Y_UNUSED(f); // shut up compiler about 'assigned value that is not used' + Y_UNUSED(f); // shut up compiler about 'assigned value that is not used' } - Y_UNIT_TEST(TestToFrom) { + Y_UNIT_TEST(TestToFrom) { test1(bool, true); test1(bool, false); test2(bool, ""); @@ -229,18 +229,18 @@ Y_UNIT_TEST_SUITE(TCastTest) { test1(long long int, LLONG_MIN + 1); } - Y_UNIT_TEST(TestVolatile) { + Y_UNIT_TEST(TestVolatile) { volatile int x = 1; UNIT_ASSERT_VALUES_EQUAL(ToString(x), "1"); } - Y_UNIT_TEST(TestStrToD) { - UNIT_ASSERT_DOUBLES_EQUAL(StrToD("1.1", nullptr), 1.1, EPS); - UNIT_ASSERT_DOUBLES_EQUAL(StrToD("1.12345678", nullptr), 1.12345678, EPS); - UNIT_ASSERT_DOUBLES_EQUAL(StrToD("10E-5", nullptr), 10E-5, EPS); - UNIT_ASSERT_DOUBLES_EQUAL(StrToD("1.1E+5", nullptr), 1.1E+5, EPS); + Y_UNIT_TEST(TestStrToD) { + UNIT_ASSERT_DOUBLES_EQUAL(StrToD("1.1", nullptr), 1.1, EPS); + UNIT_ASSERT_DOUBLES_EQUAL(StrToD("1.12345678", nullptr), 1.12345678, EPS); + UNIT_ASSERT_DOUBLES_EQUAL(StrToD("10E-5", nullptr), 10E-5, EPS); + UNIT_ASSERT_DOUBLES_EQUAL(StrToD("1.1E+5", nullptr), 1.1E+5, EPS); - char* ret = nullptr; + char* ret = nullptr; UNIT_ASSERT_DOUBLES_EQUAL(StrToD("1.1y", &ret), 1.1, EPS); UNIT_ASSERT_VALUES_EQUAL(*ret, 'y'); @@ -252,7 +252,7 @@ Y_UNIT_TEST_SUITE(TCastTest) { UNIT_ASSERT_VALUES_EQUAL(*ret, 'z'); } - Y_UNIT_TEST(TestFloats) { + Y_UNIT_TEST(TestFloats) { // "%g" mode UNIT_ASSERT_VALUES_EQUAL(FloatToString(0.1f, PREC_NDIGITS, 6), "0.1"); // drop trailing zeroes UNIT_ASSERT_VALUES_EQUAL(FloatToString(0.12345678f, PREC_NDIGITS, 6), "0.123457"); @@ -289,7 +289,7 @@ Y_UNIT_TEST_SUITE(TCastTest) { UNIT_ASSERT_STRINGS_EQUAL(FloatToString(-std::numeric_limits<float>::infinity()), "-inf"); } - Y_UNIT_TEST(TestReadFloats) { + Y_UNIT_TEST(TestReadFloats) { GoodFloatTester<float>("0.0001", 0.0001f, EPS); GoodFloatTester<double>("0.0001", 0.0001, EPS); GoodFloatTester<long double>("0.0001", 0.0001, EPS); @@ -303,24 +303,24 @@ Y_UNIT_TEST_SUITE(TCastTest) { //BadFloatTester<float>("10E"); //BadFloatTester<float>("10.E"); BadFloatTester<float>("..0"); - BadFloatTester<float>(""); // IGNIETFERRO-300 + BadFloatTester<float>(""); // IGNIETFERRO-300 BadFloatTester<double>("1.00.01"); BadFloatTester<double>("1.0001E5b"); BadFloatTester<double>("1.0001s"); BadFloatTester<double>("1..01"); - BadFloatTester<double>(""); // IGNIETFERRO-300 + BadFloatTester<double>(""); // IGNIETFERRO-300 BadFloatTester<long double>(".1.00"); BadFloatTester<long double>("1.00."); BadFloatTester<long double>("1.0001e5-"); BadFloatTester<long double>("10e 2"); - BadFloatTester<long double>(""); // IGNIETFERRO-300 + BadFloatTester<long double>(""); // IGNIETFERRO-300 } - Y_UNIT_TEST(TestLiteral) { + Y_UNIT_TEST(TestLiteral) { UNIT_ASSERT_VALUES_EQUAL(ToString("abc"), TString("abc")); } - Y_UNIT_TEST(TestFromStringStringBuf) { + Y_UNIT_TEST(TestFromStringStringBuf) { TString a = "xyz"; TStringBuf b = FromString<TStringBuf>(a); UNIT_ASSERT_VALUES_EQUAL(a, b); @@ -328,7 +328,7 @@ Y_UNIT_TEST_SUITE(TCastTest) { } #if 0 - Y_UNIT_TEST(TestBufferOverflow) { + Y_UNIT_TEST(TestBufferOverflow) { CheckConvertToBuffer<float>(1.f, 5, "1"); CheckConvertToBuffer<float>(1.005f, 3, "1.005"); CheckConvertToBuffer<float>(1.00000000f, 3, "1"); @@ -349,7 +349,7 @@ Y_UNIT_TEST_SUITE(TCastTest) { } #endif - Y_UNIT_TEST(TestWide) { + Y_UNIT_TEST(TestWide) { TUtf16String iw = u"-100500"; int iv = 0; UNIT_ASSERT_VALUES_EQUAL(TryFromString(iw, iv), true); @@ -371,7 +371,7 @@ Y_UNIT_TEST_SUITE(TCastTest) { UNIT_ASSERT_VALUES_EQUAL(uv, 21474836470ull); } - Y_UNIT_TEST(TestDefault) { + Y_UNIT_TEST(TestDefault) { size_t res = 0; const size_t def1 = 42; @@ -437,7 +437,7 @@ Y_UNIT_TEST_SUITE(TCastTest) { UNIT_ASSERT_VALUES_EQUAL(FromStringWithDefault<size_t>(s4), size_t()); } - Y_UNIT_TEST(TestBool) { + Y_UNIT_TEST(TestBool) { // True cases UNIT_ASSERT_VALUES_EQUAL(FromString<bool>("yes"), true); UNIT_ASSERT_VALUES_EQUAL(FromString<bool>("1"), true); @@ -449,7 +449,7 @@ Y_UNIT_TEST_SUITE(TCastTest) { UNIT_ASSERT_EXCEPTION(FromString<bool>("something"), yexception); } - Y_UNIT_TEST(TestAutoDetectType) { + Y_UNIT_TEST(TestAutoDetectType) { UNIT_ASSERT_DOUBLES_EQUAL((float)FromString("0.0001"), 0.0001, EPS); UNIT_ASSERT_DOUBLES_EQUAL((double)FromString("0.0015", sizeof("0.0015") - 2), 0.001, EPS); UNIT_ASSERT_DOUBLES_EQUAL((long double)FromString(TStringBuf("0.0001")), 0.0001, EPS); @@ -472,7 +472,7 @@ Y_UNIT_TEST_SUITE(TCastTest) { } } - Y_UNIT_TEST(ErrorMessages) { + Y_UNIT_TEST(ErrorMessages) { try { FromString<ui32>(""); UNIT_ASSERT(false); @@ -509,47 +509,47 @@ Y_UNIT_TEST_SUITE(TCastTest) { CheckMessage(e, "Unexpected symbol \".\" at pos 1 in string \"0.328413745072\""); } } - - Y_UNIT_TEST(TryStringBuf) { - { + + Y_UNIT_TEST(TryStringBuf) { + { constexpr TStringBuf hello = "hello"; - TStringBuf out; - UNIT_ASSERT(TryFromString(hello, out)); + TStringBuf out; + UNIT_ASSERT(TryFromString(hello, out)); UNIT_ASSERT_VALUES_EQUAL(hello, out); - } - { + } + { constexpr TStringBuf empty = ""; - TStringBuf out; - UNIT_ASSERT(TryFromString(empty, out)); + TStringBuf out; + UNIT_ASSERT(TryFromString(empty, out)); UNIT_ASSERT_VALUES_EQUAL(empty, out); - } - { - constexpr TStringBuf empty; - TStringBuf out; - UNIT_ASSERT(TryFromString(empty, out)); + } + { + constexpr TStringBuf empty; + TStringBuf out; + UNIT_ASSERT(TryFromString(empty, out)); UNIT_ASSERT_VALUES_EQUAL(empty, out); - } - { + } + { const auto hello = u"hello"; - TWtringBuf out; - UNIT_ASSERT(TryFromString(hello, out)); + TWtringBuf out; + UNIT_ASSERT(TryFromString(hello, out)); UNIT_ASSERT_VALUES_EQUAL(hello, out); - } - { + } + { const TUtf16String empty; - TWtringBuf out; - UNIT_ASSERT(TryFromString(empty, out)); + TWtringBuf out; + UNIT_ASSERT(TryFromString(empty, out)); UNIT_ASSERT_VALUES_EQUAL(empty, out); - } - { - constexpr TWtringBuf empty; - TWtringBuf out; - UNIT_ASSERT(TryFromString(empty, out)); + } + { + constexpr TWtringBuf empty; + TWtringBuf out; + UNIT_ASSERT(TryFromString(empty, out)); UNIT_ASSERT_VALUES_EQUAL(empty, out); - } - } + } + } - Y_UNIT_TEST(Nan) { + Y_UNIT_TEST(Nan) { double xx = 0; UNIT_ASSERT(!TryFromString("NaN", xx)); @@ -557,7 +557,7 @@ Y_UNIT_TEST_SUITE(TCastTest) { UNIT_ASSERT(!TryFromString("nan", xx)); } - Y_UNIT_TEST(Infinity) { + Y_UNIT_TEST(Infinity) { double xx = 0; UNIT_ASSERT(!TryFromString("Infinity", xx)); @@ -565,7 +565,7 @@ Y_UNIT_TEST_SUITE(TCastTest) { UNIT_ASSERT(!TryFromString("infinity", xx)); } - Y_UNIT_TEST(TestBorderCases) { + Y_UNIT_TEST(TestBorderCases) { UNIT_ASSERT_VALUES_EQUAL(ToString(0.0), "0"); UNIT_ASSERT_VALUES_EQUAL(ToString(1.0), "1"); UNIT_ASSERT_VALUES_EQUAL(ToString(10.0), "10"); diff --git a/util/string/escape.cpp b/util/string/escape.cpp index 0a79bd30d0..cd09a7dbd0 100644 --- a/util/string/escape.cpp +++ b/util/string/escape.cpp @@ -43,7 +43,7 @@ namespace { template <typename TChar> static inline char HexDigit(TChar value) { - Y_ASSERT(value < 16); + Y_ASSERT(value < 16); if (value < 10) { return '0' + value; } else { @@ -53,7 +53,7 @@ namespace { template <typename TChar> static inline char OctDigit(TChar value) { - Y_ASSERT(value < 8); + Y_ASSERT(value < 8); return '0' + value; } diff --git a/util/string/escape_ut.cpp b/util/string/escape_ut.cpp index b1bd7f2a94..cd38ecffd3 100644 --- a/util/string/escape_ut.cpp +++ b/util/string/escape_ut.cpp @@ -7,20 +7,20 @@ using namespace std::string_view_literals; -namespace { - struct TExample { +namespace { + struct TExample { TString Expected; TString Source; - - TExample(const TStringBuf expected, const TStringBuf source) - : Expected{expected} + + TExample(const TStringBuf expected, const TStringBuf source) + : Expected{expected} , Source{source} { - } - }; -} - -static const TExample CommonTestData[] = { + } + }; +} + +static const TExample CommonTestData[] = { // Should be valid UTF-8. {"http://ya.ru/", "http://ya.ru/"}, {"http://ya.ru/\\x17\\n", "http://ya.ru/\x17\n"}, @@ -46,16 +46,16 @@ static const TExample CommonTestData[] = { {"There are questions \\x3F?", "There are questions ??"}, }; -Y_UNIT_TEST_SUITE(TEscapeCTest) { - Y_UNIT_TEST(TestStrokaEscapeC) { - for (const auto& e : CommonTestData) { +Y_UNIT_TEST_SUITE(TEscapeCTest) { + Y_UNIT_TEST(TestStrokaEscapeC) { + for (const auto& e : CommonTestData) { TString expected(e.Expected); TString source(e.Source); TString actual(EscapeC(e.Source)); TString actual2(UnescapeC(e.Expected)); - UNIT_ASSERT_VALUES_EQUAL(e.Expected, actual); - UNIT_ASSERT_VALUES_EQUAL(e.Source, actual2); + UNIT_ASSERT_VALUES_EQUAL(e.Expected, actual); + UNIT_ASSERT_VALUES_EQUAL(e.Source, actual2); } UNIT_ASSERT_VALUES_EQUAL("http://ya.ru/\\x17\\n\\xAB", EscapeC(TString("http://ya.ru/\x17\n\xab"))); @@ -79,8 +79,8 @@ Y_UNIT_TEST_SUITE(TEscapeCTest) { UNIT_ASSERT_VALUES_EQUAL("Странный компроматтест", UnescapeC(TString("\\u0421\\u0442\\u0440\\u0430\\u043d\\u043d\\u044b\\u0439 \\u043a\\u043e\\u043c\\u043f\\u0440\\u043e\\u043c\\u0430\\u0442тест"))); } - Y_UNIT_TEST(TestWtrokaEscapeC) { - for (const auto& e : CommonTestData) { + Y_UNIT_TEST(TestWtrokaEscapeC) { + for (const auto& e : CommonTestData) { TUtf16String expected(UTF8ToWide(e.Expected)); TUtf16String source(UTF8ToWide(e.Source)); TUtf16String actual(EscapeC(source)); @@ -95,7 +95,7 @@ Y_UNIT_TEST_SUITE(TEscapeCTest) { UNIT_ASSERT_VALUES_EQUAL(u"\\xFF", EscapeC(wchar16(255))); } - Y_UNIT_TEST(TestEscapeTrigraphs) { + Y_UNIT_TEST(TestEscapeTrigraphs) { UNIT_ASSERT_VALUES_EQUAL("?", EscapeC(TString("?"))); UNIT_ASSERT_VALUES_EQUAL("\\x3F?", EscapeC(TString("??"))); UNIT_ASSERT_VALUES_EQUAL("\\x3F\\x3F?", EscapeC(TString("???"))); @@ -104,7 +104,7 @@ Y_UNIT_TEST_SUITE(TEscapeCTest) { UNIT_ASSERT_VALUES_EQUAL("\\x3F?x\\x3F\\x3F?z", EscapeC(TString("??x???z"))); } - Y_UNIT_TEST(TestUnescapeCCharLen) { + Y_UNIT_TEST(TestUnescapeCCharLen) { auto test = [](const char* str, size_t len) { UNIT_ASSERT_EQUAL(UnescapeCCharLen(str, str + strlen(str)), len); }; @@ -131,7 +131,7 @@ Y_UNIT_TEST_SUITE(TEscapeCTest) { test("\\4xxx", 2); } - Y_UNIT_TEST(TestUnbounded) { + Y_UNIT_TEST(TestUnbounded) { char buf[100000]; for (const auto& x : CommonTestData) { diff --git a/util/string/fuzzing/escape_c/main.cpp b/util/string/fuzzing/escape_c/main.cpp index aa733cec76..742126416a 100644 --- a/util/string/fuzzing/escape_c/main.cpp +++ b/util/string/fuzzing/escape_c/main.cpp @@ -1,11 +1,11 @@ -#include <util/generic/string.h> -#include <util/string/escape.h> - -extern "C" int LLVMFuzzerTestOneInput(const ui8* const data, const size_t size) { - const TString src(reinterpret_cast<const char*>(data), size); - const auto escaped = EscapeC(src); - const auto dst = UnescapeC(escaped); - - Y_VERIFY(src == dst); - return 0; -} +#include <util/generic/string.h> +#include <util/string/escape.h> + +extern "C" int LLVMFuzzerTestOneInput(const ui8* const data, const size_t size) { + const TString src(reinterpret_cast<const char*>(data), size); + const auto escaped = EscapeC(src); + const auto dst = UnescapeC(escaped); + + Y_VERIFY(src == dst); + return 0; +} diff --git a/util/string/fuzzing/escape_c/ya.make b/util/string/fuzzing/escape_c/ya.make index 0cdee23d31..61e64ac9de 100644 --- a/util/string/fuzzing/escape_c/ya.make +++ b/util/string/fuzzing/escape_c/ya.make @@ -1,13 +1,13 @@ -OWNER( - yazevnul - g:util -) +OWNER( + yazevnul + g:util +) SUBSCRIBER(g:util-subscribers) - -FUZZ() - -SRCS( - main.cpp -) - -END() + +FUZZ() + +SRCS( + main.cpp +) + +END() diff --git a/util/string/fuzzing/ya.make b/util/string/fuzzing/ya.make index e3a87d3740..617e0f2b1d 100644 --- a/util/string/fuzzing/ya.make +++ b/util/string/fuzzing/ya.make @@ -1,11 +1,11 @@ -OWNER( +OWNER( g:util - pg -) + pg +) SUBSCRIBER(g:util-subscribers) - + RECURSE( - collapse - escape_c + collapse + escape_c strtod ) diff --git a/util/string/hex.h b/util/string/hex.h index 08f7398129..af3d2d528f 100644 --- a/util/string/hex.h +++ b/util/string/hex.h @@ -16,7 +16,7 @@ extern const char* const Char2DigitTable; inline static int Char2Digit(char ch) { char result = Char2DigitTable[(unsigned char)ch]; - Y_ENSURE(result != '\xff', "invalid hex character " << (int)ch); + Y_ENSURE(result != '\xff', "invalid hex character " << (int)ch); return result; } diff --git a/util/string/hex_ut.cpp b/util/string/hex_ut.cpp index 485583ce35..39a83d5e62 100644 --- a/util/string/hex_ut.cpp +++ b/util/string/hex_ut.cpp @@ -2,16 +2,16 @@ #include <library/cpp/testing/unittest/registar.h> -Y_UNIT_TEST_SUITE(THexCodingTest) { - Y_UNIT_TEST(TestEncode) { +Y_UNIT_TEST_SUITE(THexCodingTest) { + Y_UNIT_TEST(TestEncode) { UNIT_ASSERT_EQUAL(HexEncode("i1634iqwbf,&msdb"), "693136333469717762662C266D736462"); } - Y_UNIT_TEST(TestDecode) { + Y_UNIT_TEST(TestDecode) { UNIT_ASSERT_EQUAL(HexDecode("693136333469717762662C266D736462"), "i1634iqwbf,&msdb"); } - Y_UNIT_TEST(TestDecodeCase) { + Y_UNIT_TEST(TestDecodeCase) { UNIT_ASSERT_EQUAL(HexDecode("12ABCDEF"), HexDecode("12abcdef")); UNIT_ASSERT_EXCEPTION(HexDecode("Hello"), yexception); //< incorrect chars UNIT_ASSERT_EXCEPTION(HexDecode("123"), yexception); //< odd length diff --git a/util/string/join_ut.cpp b/util/string/join_ut.cpp index fde333a37d..3ed2b2459c 100644 --- a/util/string/join_ut.cpp +++ b/util/string/join_ut.cpp @@ -3,7 +3,7 @@ #include <library/cpp/testing/unittest/registar.h> #include <util/generic/vector.h> -#include <util/stream/output.h> +#include <util/stream/output.h> struct TCustomData { TVector<int> Ints; @@ -13,8 +13,8 @@ TString ToString(const TCustomData& d) { return JoinSeq("__", d.Ints); } -Y_UNIT_TEST_SUITE(JoinStringTest) { - Y_UNIT_TEST(ScalarItems) { +Y_UNIT_TEST_SUITE(JoinStringTest) { + Y_UNIT_TEST(ScalarItems) { UNIT_ASSERT_EQUAL(Join(',', 10, 11.1, "foobar"), "10,11.1,foobar"); UNIT_ASSERT_EQUAL(Join(", ", 10, 11.1, "foobar"), "10, 11.1, foobar"); UNIT_ASSERT_EQUAL(Join(", ", 10, 11.1, TString("foobar")), "10, 11.1, foobar"); @@ -26,7 +26,7 @@ Y_UNIT_TEST_SUITE(JoinStringTest) { UNIT_ASSERT_EQUAL(Join(" ", "a", "b", "", "c"), "a b c"); } - Y_UNIT_TEST(IntContainerItems) { + Y_UNIT_TEST(IntContainerItems) { int v[] = {1, 2, 3}; TVector<int> vv(v, v + 3); UNIT_ASSERT_EQUAL(JoinSeq(" ", vv), "1 2 3"); @@ -38,7 +38,7 @@ Y_UNIT_TEST_SUITE(JoinStringTest) { UNIT_ASSERT_VALUES_EQUAL(JoinSeq(" ", v), "1 2 3"); } - Y_UNIT_TEST(StrContainerItems) { + Y_UNIT_TEST(StrContainerItems) { // try various overloads and template type arguments static const char* const result = "1 22 333"; static const char* const v[] = {"1", "22", "333"}; @@ -148,13 +148,13 @@ Y_UNIT_TEST_SUITE(JoinStringTest) { UNIT_ASSERT_VALUES_EQUAL(JoinSeq(" ", v), result); } - Y_UNIT_TEST(CustomToString) { - TCustomData d1{{1, 2, 3, 4, 5}}; - TCustomData d2{{0, -1, -2}}; + Y_UNIT_TEST(CustomToString) { + TCustomData d1{{1, 2, 3, 4, 5}}; + TCustomData d2{{0, -1, -2}}; UNIT_ASSERT_EQUAL(Join(" ", d1, d2), "1__2__3__4__5 0__-1__-2"); } - Y_UNIT_TEST(JoinChars) { + Y_UNIT_TEST(JoinChars) { // Note that char delimeter is printed as single char string, // but joined char values are printed as their numeric codes! O_o UNIT_ASSERT_EQUAL(Join('a', 'a', 'a'), "97a97"); diff --git a/util/string/printf.cpp b/util/string/printf.cpp index a8a2e71c9d..5b7c34d4e1 100644 --- a/util/string/printf.cpp +++ b/util/string/printf.cpp @@ -1,7 +1,7 @@ #include "printf.h" #include <util/stream/printf.h> -#include <util/stream/str.h> +#include <util/stream/str.h> int vsprintf(TString& s, const char* c, va_list params) { TStringOutput so(s.remove()); diff --git a/util/string/printf.h b/util/string/printf.h index 742bf1e584..925c6edaff 100644 --- a/util/string/printf.h +++ b/util/string/printf.h @@ -1,10 +1,10 @@ #pragma once #include <util/generic/fwd.h> -#include <util/system/compiler.h> +#include <util/system/compiler.h> + +#include <cstdarg> -#include <cstdarg> - /// formatted print. return printed length: int Y_PRINTF_FORMAT(2, 0) vsprintf(TString& s, const char* c, va_list params); /// formatted print. return printed length: diff --git a/util/string/printf_ut.cpp b/util/string/printf_ut.cpp index b6d43cb3a2..2b2f980b70 100644 --- a/util/string/printf_ut.cpp +++ b/util/string/printf_ut.cpp @@ -2,15 +2,15 @@ #include <library/cpp/testing/unittest/registar.h> -Y_UNIT_TEST_SUITE(TStringPrintf) { - Y_UNIT_TEST(TestSprintf) { +Y_UNIT_TEST_SUITE(TStringPrintf) { + Y_UNIT_TEST(TestSprintf) { TString s; int len = sprintf(s, "Hello %s", "world"); UNIT_ASSERT_EQUAL(s, TString("Hello world")); UNIT_ASSERT_EQUAL(len, 11); } - Y_UNIT_TEST(TestFcat) { + Y_UNIT_TEST(TestFcat) { TString s; int len = sprintf(s, "Hello %s", "world"); UNIT_ASSERT_EQUAL(s, TString("Hello world")); @@ -20,11 +20,11 @@ Y_UNIT_TEST_SUITE(TStringPrintf) { UNIT_ASSERT_EQUAL(len, 7); } - Y_UNIT_TEST(TestSpecial) { + Y_UNIT_TEST(TestSpecial) { UNIT_ASSERT_EQUAL("4294967295", Sprintf("%" PRIu32, (ui32)(-1))); } - Y_UNIT_TEST(TestExplicitPositions) { + Y_UNIT_TEST(TestExplicitPositions) { UNIT_ASSERT_EQUAL("abc xyz abc", Sprintf("%1$s %2$s %1$s", "abc", "xyz")); } } diff --git a/util/string/split.h b/util/string/split.h index 58d8f81c5e..bc46d9e64c 100644 --- a/util/string/split.h +++ b/util/string/split.h @@ -261,7 +261,7 @@ struct TSetDelimiter: private TFindFirstOf<const Char> { }; namespace NSplitTargetHasPushBack { - Y_HAS_MEMBER(push_back, PushBack); + Y_HAS_MEMBER(push_back, PushBack); } template <class T, class = void> diff --git a/util/string/split_ut.cpp b/util/string/split_ut.cpp index 0135d5c3af..43e59f2d75 100644 --- a/util/string/split_ut.cpp +++ b/util/string/split_ut.cpp @@ -2,7 +2,7 @@ #include <library/cpp/testing/unittest/registar.h> -#include <util/stream/output.h> +#include <util/stream/output.h> #include <util/charset/wide.h> #include <util/datetime/cputimer.h> #include <util/generic/maybe.h> @@ -119,8 +119,8 @@ void TestLimitingConsumerOnRange(TVector<TString>& good, const char* b, const ch UNIT_ASSERT_EQUAL(TString(limits.Last), TString(last)); } -Y_UNIT_TEST_SUITE(SplitStringTest) { - Y_UNIT_TEST(TestCharSingleDelimiter) { +Y_UNIT_TEST_SUITE(SplitStringTest) { + Y_UNIT_TEST(TestCharSingleDelimiter) { TString data("qw ab qwabcab"); TString canonic[] = {"qw", "ab", "", "qwabcab"}; TVector<TString> good(canonic, canonic + 4); @@ -130,7 +130,7 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TestDelimiterOnRange<TContainerConsumer>(good, data.data(), data.end(), delim); } - Y_UNIT_TEST(TestWideSingleDelimiter) { + Y_UNIT_TEST(TestWideSingleDelimiter) { TUtf16String data(u"qw ab qwabcab"); TUtf16String canonic[] = {u"qw", u"ab", TUtf16String(), u"qwabcab"}; TVector<TUtf16String> good(canonic, canonic + 4); @@ -140,7 +140,7 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TestDelimiterOnRange<TContainerConsumer>(good, data.data(), data.end(), delim); } - Y_UNIT_TEST(TestConvertToIntCharSingleDelimiter) { + Y_UNIT_TEST(TestConvertToIntCharSingleDelimiter) { TString data("42 4242 -12345 0"); i32 canonic[] = {42, 4242, -12345, 0}; TVector<i32> good(canonic, canonic + 4); @@ -159,7 +159,7 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TestConsumerOnRange<TSkipEmptyTokens<TStrokaConsumer>>(good, data.data(), data.end(), " "); } - Y_UNIT_TEST(TestCharKeepDelimiters) { + Y_UNIT_TEST(TestCharKeepDelimiters) { TString data("qw ab qwabcab "); TString canonic[] = {"qw", " ", "ab", " ", "", " ", "qwabcab", " ", ""}; TVector<TString> good(canonic, canonic + 9); @@ -168,7 +168,7 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TestConsumerOnRange<TKeepDelimiters<TStrokaConsumer>>(good, data.data(), data.end(), " "); } - Y_UNIT_TEST(TestCharLimit) { + Y_UNIT_TEST(TestCharLimit) { TString data("qw ab qwabcab "); TString canonic[] = {"qw", "ab"}; TVector<TString> good(canonic, canonic + 2); @@ -177,7 +177,7 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TestLimitingConsumerOnRange(good, data.data(), data.end(), " ", 3, " qwabcab "); } - Y_UNIT_TEST(TestCharStringDelimiter) { + Y_UNIT_TEST(TestCharStringDelimiter) { TString data("qw ab qwababcab"); TString canonic[] = {"qw ", " qw", "", "c", ""}; TVector<TString> good(canonic, canonic + 5); @@ -187,7 +187,7 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TestDelimiterOnRange<TContainerConsumer>(good, data.data(), data.end(), delim); } - Y_UNIT_TEST(TestWideStringDelimiter) { + Y_UNIT_TEST(TestWideStringDelimiter) { TUtf16String data(u"qw ab qwababcab"); TUtf16String canonic[] = {u"qw ", u" qw", TUtf16String(), u"c", TUtf16String()}; TVector<TUtf16String> good(canonic, canonic + 5); @@ -198,7 +198,7 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TestDelimiterOnRange<TContainerConsumer>(good, data.data(), data.end(), delim); } - Y_UNIT_TEST(TestCharSetDelimiter) { + Y_UNIT_TEST(TestCharSetDelimiter) { TString data("qw ab qwababccab"); TString canonic[] = {"q", " ab q", "abab", "", "ab"}; TVector<TString> good(canonic, canonic + 5); @@ -208,7 +208,7 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TestDelimiterOnRange<TContainerConsumer>(good, data.data(), data.end(), delim); } - Y_UNIT_TEST(TestWideSetDelimiter) { + Y_UNIT_TEST(TestWideSetDelimiter) { TUtf16String data(u"qw ab qwababccab"); TUtf16String canonic[] = {u"q", u" ab q", u"abab", TUtf16String(), u"ab"}; TVector<TUtf16String> good(canonic, canonic + 5); @@ -218,7 +218,7 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { TestDelimiterOnString<TContainerConsumer>(good, data.data(), delim); } - Y_UNIT_TEST(TestWideSetDelimiterRange) { + Y_UNIT_TEST(TestWideSetDelimiterRange) { TUtf16String data(u"qw ab qwababccab"); TUtf16String canonic[] = {u"q", u" ab q", u"abab", TUtf16String(), u"ab"}; TVector<TUtf16String> good(1); @@ -237,7 +237,7 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { Cmp(good, test); } - Y_UNIT_TEST(TestSplit) { + Y_UNIT_TEST(TestSplit) { TString data("qw ab qwababcba"); TString canonic[] = {"qw ", " qw", "c"}; TVector<TString> good(canonic, canonic + 3); @@ -251,7 +251,7 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { Cmp(good, test1); } - Y_UNIT_TEST(ConvenientSplitTest) { + Y_UNIT_TEST(ConvenientSplitTest) { TString data("abc 22 33.5 xyz"); TString str; int num1 = 0; @@ -264,7 +264,7 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { UNIT_ASSERT_VALUES_EQUAL(strBuf, "xyz"); } - Y_UNIT_TEST(ConvenientSplitTestWithMaybe) { + Y_UNIT_TEST(ConvenientSplitTestWithMaybe) { TString data("abc 42"); TString str; TMaybe<double> num2 = 1; @@ -277,7 +277,7 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { UNIT_ASSERT(!maybe); } - Y_UNIT_TEST(ConvenientSplitTestExceptions) { + Y_UNIT_TEST(ConvenientSplitTestExceptions) { TString data("abc 22 33"); TString s1, s2, s3, s4; @@ -286,7 +286,7 @@ Y_UNIT_TEST_SUITE(SplitStringTest) { UNIT_ASSERT_EXCEPTION(Split(data, ' ', s1, s2, s3, s4), yexception); } - Y_UNIT_TEST(ConvenientSplitTestMaybeExceptions) { + Y_UNIT_TEST(ConvenientSplitTestMaybeExceptions) { TString data("abc 22 33"); TString s1, s2; TMaybe<TString> m1, m2; diff --git a/util/string/strip_ut.cpp b/util/string/strip_ut.cpp index 663b648a21..d1029d1498 100644 --- a/util/string/strip_ut.cpp +++ b/util/string/strip_ut.cpp @@ -4,8 +4,8 @@ #include <util/charset/wide.h> -Y_UNIT_TEST_SUITE(TStripStringTest) { - Y_UNIT_TEST(TestStrip) { +Y_UNIT_TEST_SUITE(TStripStringTest) { + Y_UNIT_TEST(TestStrip) { struct TTest { const char* Str; const char* StripLeftRes; @@ -26,25 +26,25 @@ Y_UNIT_TEST_SUITE(TStripStringTest) { {"a c", "a c", "a c", "a c"}, }; - for (const auto& test : tests) { + for (const auto& test : tests) { TString inputStr(test.Str); TString s; Strip(inputStr, s); - UNIT_ASSERT_EQUAL(s, test.StripRes); + UNIT_ASSERT_EQUAL(s, test.StripRes); - UNIT_ASSERT_EQUAL(StripString(inputStr), test.StripRes); - UNIT_ASSERT_EQUAL(StripStringLeft(inputStr), test.StripLeftRes); - UNIT_ASSERT_EQUAL(StripStringRight(inputStr), test.StripRightRes); + UNIT_ASSERT_EQUAL(StripString(inputStr), test.StripRes); + UNIT_ASSERT_EQUAL(StripStringLeft(inputStr), test.StripLeftRes); + UNIT_ASSERT_EQUAL(StripStringRight(inputStr), test.StripRightRes); - TStringBuf inputStrBuf(test.Str); - UNIT_ASSERT_EQUAL(StripString(inputStrBuf), test.StripRes); - UNIT_ASSERT_EQUAL(StripStringLeft(inputStrBuf), test.StripLeftRes); - UNIT_ASSERT_EQUAL(StripStringRight(inputStrBuf), test.StripRightRes); + TStringBuf inputStrBuf(test.Str); + UNIT_ASSERT_EQUAL(StripString(inputStrBuf), test.StripRes); + UNIT_ASSERT_EQUAL(StripStringLeft(inputStrBuf), test.StripLeftRes); + UNIT_ASSERT_EQUAL(StripStringRight(inputStrBuf), test.StripRightRes); }; } - Y_UNIT_TEST(TestCustomStrip) { + Y_UNIT_TEST(TestCustomStrip) { struct TTest { const char* Str; const char* Result; @@ -56,14 +56,14 @@ Y_UNIT_TEST_SUITE(TStripStringTest) { {"012//", "012"}, }; - for (auto test : tests) { + for (auto test : tests) { UNIT_ASSERT_EQUAL( StripString(TString(test.Str), EqualsStripAdapter('/')), - test.Result); + test.Result); }; } - Y_UNIT_TEST(TestCustomStripLeftRight) { + Y_UNIT_TEST(TestCustomStripLeftRight) { struct TTest { const char* Str; const char* ResultLeft; @@ -76,30 +76,30 @@ Y_UNIT_TEST_SUITE(TStripStringTest) { {"012//", "012//", "012"}, }; - for (const auto& test : tests) { + for (const auto& test : tests) { UNIT_ASSERT_EQUAL( StripStringLeft(TString(test.Str), EqualsStripAdapter('/')), - test.ResultLeft); + test.ResultLeft); UNIT_ASSERT_EQUAL( StripStringRight(TString(test.Str), EqualsStripAdapter('/')), - test.ResultRight); + test.ResultRight); }; } - Y_UNIT_TEST(TestNullStringStrip) { - TStringBuf nullString(nullptr, nullptr); + Y_UNIT_TEST(TestNullStringStrip) { + TStringBuf nullString(nullptr, nullptr); UNIT_ASSERT_EQUAL( StripString(nullString), TString()); } - Y_UNIT_TEST(TestWtrokaStrip) { + Y_UNIT_TEST(TestWtrokaStrip) { UNIT_ASSERT_EQUAL(StripString(TWtringBuf(u" abc ")), u"abc"); UNIT_ASSERT_EQUAL(StripStringLeft(TWtringBuf(u" abc ")), u"abc "); UNIT_ASSERT_EQUAL(StripStringRight(TWtringBuf(u" abc ")), u" abc"); } - Y_UNIT_TEST(TestWtrokaCustomStrip) { + Y_UNIT_TEST(TestWtrokaCustomStrip) { UNIT_ASSERT_EQUAL( StripString( TWtringBuf(u"/abc/"), @@ -107,7 +107,7 @@ Y_UNIT_TEST_SUITE(TStripStringTest) { u"abc"); } - Y_UNIT_TEST(TestCollapse) { + Y_UNIT_TEST(TestCollapse) { TString s; Collapse(TString(" 123 456 "), s); UNIT_ASSERT(s == " 123 456 "); @@ -124,7 +124,7 @@ Y_UNIT_TEST_SUITE(TStripStringTest) { #endif } - Y_UNIT_TEST(TestCollapseText) { + Y_UNIT_TEST(TestCollapseText) { TString abs1("Very long description string written in unknown language."); TString abs2(abs1); TString abs3(abs1); diff --git a/util/string/subst.cpp b/util/string/subst.cpp index 8daef0708b..b2df328dc1 100644 --- a/util/string/subst.cpp +++ b/util/string/subst.cpp @@ -1,200 +1,200 @@ #include "subst.h" - -#include <util/generic/strbuf.h> -#include <util/generic/string.h> -#include <util/system/compiler.h> - -#include <string> -#include <type_traits> - -// a bit of template magic (to be fast and unreadable) -template <class TStringType, class TTo, bool Main> -static Y_FORCE_INLINE void MoveBlock(typename TStringType::value_type* ptr, size_t& srcPos, size_t& dstPos, const size_t off, const TTo to, const size_t toSize) { - const size_t unchangedSize = off - srcPos; - if (dstPos < srcPos) { - for (size_t i = 0; i < unchangedSize; ++i) { - ptr[dstPos++] = ptr[srcPos++]; - } - } else { - dstPos += unchangedSize; - srcPos += unchangedSize; - } - - if (Main) { - for (size_t i = 0; i < toSize; ++i) { - ptr[dstPos++] = to[i]; - } - } -} - -template <typename T, typename U> -static bool IsIntersect(const T& a, const U& b) noexcept { - if (b.data() < a.data()) { - return IsIntersect(b, a); - } - - return !a.empty() && !b.empty() && - ((a.data() <= b.data() && b.data() < a.data() + a.size()) || - (a.data() < b.data() + b.size() && b.data() + b.size() <= a.data() + a.size())); -} - -/** - * Replaces all occurences of substring @c from in string @c s to string @c to. - * Uses two separate implementations (inplace for shrink and append for grow case) - * See IGNIETFERRO-394 - **/ + +#include <util/generic/strbuf.h> +#include <util/generic/string.h> +#include <util/system/compiler.h> + +#include <string> +#include <type_traits> + +// a bit of template magic (to be fast and unreadable) +template <class TStringType, class TTo, bool Main> +static Y_FORCE_INLINE void MoveBlock(typename TStringType::value_type* ptr, size_t& srcPos, size_t& dstPos, const size_t off, const TTo to, const size_t toSize) { + const size_t unchangedSize = off - srcPos; + if (dstPos < srcPos) { + for (size_t i = 0; i < unchangedSize; ++i) { + ptr[dstPos++] = ptr[srcPos++]; + } + } else { + dstPos += unchangedSize; + srcPos += unchangedSize; + } + + if (Main) { + for (size_t i = 0; i < toSize; ++i) { + ptr[dstPos++] = to[i]; + } + } +} + +template <typename T, typename U> +static bool IsIntersect(const T& a, const U& b) noexcept { + if (b.data() < a.data()) { + return IsIntersect(b, a); + } + + return !a.empty() && !b.empty() && + ((a.data() <= b.data() && b.data() < a.data() + a.size()) || + (a.data() < b.data() + b.size() && b.data() + b.size() <= a.data() + a.size())); +} + +/** + * Replaces all occurences of substring @c from in string @c s to string @c to. + * Uses two separate implementations (inplace for shrink and append for grow case) + * See IGNIETFERRO-394 + **/ template <class TStringType, typename TStringViewType = TBasicStringBuf<typename TStringType::value_type>> -static inline size_t SubstGlobalImpl(TStringType& s, const TStringViewType from, const TStringViewType to, size_t fromPos = 0) { +static inline size_t SubstGlobalImpl(TStringType& s, const TStringViewType from, const TStringViewType to, size_t fromPos = 0) { if (from.empty()) { - return 0; - } - - Y_ASSERT(!IsIntersect(s, from)); - Y_ASSERT(!IsIntersect(s, to)); - - const size_t fromSize = from.size(); - const size_t toSize = to.size(); - size_t replacementsCount = 0; - size_t off = fromPos; - size_t srcPos = 0; - - if (toSize > fromSize) { - // string will grow: append to another string - TStringType result; - for (; (off = TStringViewType(s).find(from, off)) != TStringType::npos; off += fromSize) { - if (!replacementsCount) { - // first replacement occured, we can prepare result string - result.reserve(s.size() + s.size() / 3); - } - result.append(s.begin() + srcPos, s.begin() + off); + return 0; + } + + Y_ASSERT(!IsIntersect(s, from)); + Y_ASSERT(!IsIntersect(s, to)); + + const size_t fromSize = from.size(); + const size_t toSize = to.size(); + size_t replacementsCount = 0; + size_t off = fromPos; + size_t srcPos = 0; + + if (toSize > fromSize) { + // string will grow: append to another string + TStringType result; + for (; (off = TStringViewType(s).find(from, off)) != TStringType::npos; off += fromSize) { + if (!replacementsCount) { + // first replacement occured, we can prepare result string + result.reserve(s.size() + s.size() / 3); + } + result.append(s.begin() + srcPos, s.begin() + off); result.append(to.data(), to.size()); - srcPos = off + fromSize; - ++replacementsCount; - } - if (replacementsCount) { - // append tail - result.append(s.begin() + srcPos, s.end()); - s = std::move(result); - } - return replacementsCount; - } - - // string will not grow: use inplace algo - size_t dstPos = 0; + srcPos = off + fromSize; + ++replacementsCount; + } + if (replacementsCount) { + // append tail + result.append(s.begin() + srcPos, s.end()); + s = std::move(result); + } + return replacementsCount; + } + + // string will not grow: use inplace algo + size_t dstPos = 0; typename TStringType::value_type* ptr = &*s.begin(); - for (; (off = TStringViewType(s).find(from, off)) != TStringType::npos; off += fromSize) { - Y_ASSERT(dstPos <= srcPos); - MoveBlock<TStringType, TStringViewType, true>(ptr, srcPos, dstPos, off, to, toSize); - srcPos = off + fromSize; - ++replacementsCount; - } - - if (replacementsCount) { - // append tail - MoveBlock<TStringType, TStringViewType, false>(ptr, srcPos, dstPos, s.size(), to, toSize); - s.resize(dstPos); - } - return replacementsCount; -} - -/// Replaces all occurences of the 'from' symbol in a string to the 'to' symbol. -template <class TStringType> -inline size_t SubstCharGlobalImpl(TStringType& s, typename TStringType::value_type from, typename TStringType::value_type to, size_t fromPos = 0) { - if (fromPos >= s.size()) { - return 0; - } - - size_t result = 0; - fromPos = s.find(from, fromPos); - - // s.begin() might cause memory copying, so call it only if needed - if (fromPos != TStringType::npos) { + for (; (off = TStringViewType(s).find(from, off)) != TStringType::npos; off += fromSize) { + Y_ASSERT(dstPos <= srcPos); + MoveBlock<TStringType, TStringViewType, true>(ptr, srcPos, dstPos, off, to, toSize); + srcPos = off + fromSize; + ++replacementsCount; + } + + if (replacementsCount) { + // append tail + MoveBlock<TStringType, TStringViewType, false>(ptr, srcPos, dstPos, s.size(), to, toSize); + s.resize(dstPos); + } + return replacementsCount; +} + +/// Replaces all occurences of the 'from' symbol in a string to the 'to' symbol. +template <class TStringType> +inline size_t SubstCharGlobalImpl(TStringType& s, typename TStringType::value_type from, typename TStringType::value_type to, size_t fromPos = 0) { + if (fromPos >= s.size()) { + return 0; + } + + size_t result = 0; + fromPos = s.find(from, fromPos); + + // s.begin() might cause memory copying, so call it only if needed + if (fromPos != TStringType::npos) { auto* it = &*s.begin() + fromPos; - *it = to; - ++result; - // at this point string is copied and it's safe to use constant s.end() to iterate + *it = to; + ++result; + // at this point string is copied and it's safe to use constant s.end() to iterate const auto* const sEnd = &*s.end(); - // unrolled loop goes first because it is more likely that `it` will be properly aligned - for (const auto* const end = sEnd - (sEnd - it) % 4; it < end;) { - if (*it == from) { - *it = to; - ++result; - } - ++it; - if (*it == from) { - *it = to; - ++result; - } - ++it; - if (*it == from) { - *it = to; - ++result; - } - ++it; - if (*it == from) { - *it = to; - ++result; - } - ++it; - } - for (; it < sEnd; ++it) { - if (*it == from) { - *it = to; - ++result; - } - } - } - - return result; -} - -/* Standard says that `char16_t` is a distinct type and has same size, signedness and alignment as - * `std::uint_least16_t`, so we check if `char16_t` has same signedness and size as `wchar16` to be - * sure that we can make safe casts between values of these types and pointers. - */ -static_assert(sizeof(wchar16) == sizeof(char16_t), ""); + // unrolled loop goes first because it is more likely that `it` will be properly aligned + for (const auto* const end = sEnd - (sEnd - it) % 4; it < end;) { + if (*it == from) { + *it = to; + ++result; + } + ++it; + if (*it == from) { + *it = to; + ++result; + } + ++it; + if (*it == from) { + *it = to; + ++result; + } + ++it; + if (*it == from) { + *it = to; + ++result; + } + ++it; + } + for (; it < sEnd; ++it) { + if (*it == from) { + *it = to; + ++result; + } + } + } + + return result; +} + +/* Standard says that `char16_t` is a distinct type and has same size, signedness and alignment as + * `std::uint_least16_t`, so we check if `char16_t` has same signedness and size as `wchar16` to be + * sure that we can make safe casts between values of these types and pointers. + */ +static_assert(sizeof(wchar16) == sizeof(char16_t), ""); static_assert(sizeof(wchar32) == sizeof(char32_t), ""); -static_assert(std::is_unsigned<wchar16>::value == std::is_unsigned<char16_t>::value, ""); +static_assert(std::is_unsigned<wchar16>::value == std::is_unsigned<char16_t>::value, ""); static_assert(std::is_unsigned<wchar32>::value == std::is_unsigned<char32_t>::value, ""); - -size_t SubstGlobal(TString& text, const TStringBuf what, const TStringBuf with, size_t from) { - return SubstGlobalImpl(text, what, with, from); -} - -size_t SubstGlobal(std::string& text, const TStringBuf what, const TStringBuf with, size_t from) { - return SubstGlobalImpl(text, what, with, from); -} - -size_t SubstGlobal(TUtf16String& text, const TWtringBuf what, const TWtringBuf with, size_t from) { - return SubstGlobalImpl(text, what, with, from); -} - + +size_t SubstGlobal(TString& text, const TStringBuf what, const TStringBuf with, size_t from) { + return SubstGlobalImpl(text, what, with, from); +} + +size_t SubstGlobal(std::string& text, const TStringBuf what, const TStringBuf with, size_t from) { + return SubstGlobalImpl(text, what, with, from); +} + +size_t SubstGlobal(TUtf16String& text, const TWtringBuf what, const TWtringBuf with, size_t from) { + return SubstGlobalImpl(text, what, with, from); +} + size_t SubstGlobal(TUtf32String& text, const TUtf32StringBuf what, const TUtf32StringBuf with, size_t from) { return SubstGlobalImpl(text, what, with, from); } -size_t SubstGlobal(std::u16string& text, const TWtringBuf what, const TWtringBuf with, size_t from) { +size_t SubstGlobal(std::u16string& text, const TWtringBuf what, const TWtringBuf with, size_t from) { return SubstGlobalImpl(text, std::u16string_view(reinterpret_cast<const char16_t*>(what.data()), what.size()), std::u16string_view(reinterpret_cast<const char16_t*>(with.data()), with.size()), from); -} - -size_t SubstGlobal(TString& text, char what, char with, size_t from) { - return SubstCharGlobalImpl(text, what, with, from); -} - -size_t SubstGlobal(std::string& text, char what, char with, size_t from) { - return SubstCharGlobalImpl(text, what, with, from); -} - -size_t SubstGlobal(TUtf16String& text, wchar16 what, wchar16 with, size_t from) { - return SubstCharGlobalImpl(text, (char16_t)what, (char16_t)with, from); -} - -size_t SubstGlobal(std::u16string& text, wchar16 what, wchar16 with, size_t from) { - return SubstCharGlobalImpl(text, (char16_t)what, (char16_t)with, from); -} +} + +size_t SubstGlobal(TString& text, char what, char with, size_t from) { + return SubstCharGlobalImpl(text, what, with, from); +} + +size_t SubstGlobal(std::string& text, char what, char with, size_t from) { + return SubstCharGlobalImpl(text, what, with, from); +} + +size_t SubstGlobal(TUtf16String& text, wchar16 what, wchar16 with, size_t from) { + return SubstCharGlobalImpl(text, (char16_t)what, (char16_t)with, from); +} + +size_t SubstGlobal(std::u16string& text, wchar16 what, wchar16 with, size_t from) { + return SubstCharGlobalImpl(text, (char16_t)what, (char16_t)with, from); +} size_t SubstGlobal(TUtf32String& text, wchar32 what, wchar32 with, size_t from) { return SubstCharGlobalImpl(text, (char32_t)what, (char32_t)with, from); diff --git a/util/string/subst.h b/util/string/subst.h index 32a2789801..45b622fbef 100644 --- a/util/string/subst.h +++ b/util/string/subst.h @@ -1,44 +1,44 @@ #pragma once -#include <util/generic/fwd.h> +#include <util/generic/fwd.h> -#include <stlfwd> +#include <stlfwd> -/* Replace all occurences of substring `what` with string `with` starting from position `from`. - * - * @param text String to modify. - * @param what Substring to replace. - * @param with Substring to use as replacement. - * @param from Position at with to start replacement. - * - * @return Number of replacements occured. - */ -size_t SubstGlobal(TString& text, TStringBuf what, TStringBuf with, size_t from = 0); -size_t SubstGlobal(std::string& text, TStringBuf what, TStringBuf with, size_t from = 0); -size_t SubstGlobal(TUtf16String& text, TWtringBuf what, TWtringBuf with, size_t from = 0); -size_t SubstGlobal(std::u16string& text, TWtringBuf what, TWtringBuf with, size_t from = 0); +/* Replace all occurences of substring `what` with string `with` starting from position `from`. + * + * @param text String to modify. + * @param what Substring to replace. + * @param with Substring to use as replacement. + * @param from Position at with to start replacement. + * + * @return Number of replacements occured. + */ +size_t SubstGlobal(TString& text, TStringBuf what, TStringBuf with, size_t from = 0); +size_t SubstGlobal(std::string& text, TStringBuf what, TStringBuf with, size_t from = 0); +size_t SubstGlobal(TUtf16String& text, TWtringBuf what, TWtringBuf with, size_t from = 0); +size_t SubstGlobal(std::u16string& text, TWtringBuf what, TWtringBuf with, size_t from = 0); size_t SubstGlobal(TUtf32String& text, TUtf32StringBuf what, TUtf32StringBuf with, size_t from = 0); -/* Replace all occurences of character `what` with character `with` starting from position `from`. - * - * @param text String to modify. - * @param what Character to replace. - * @param with Character to use as replacement. - * @param from Position at with to start replacement. - * - * @return Number of replacements occured. - */ -size_t SubstGlobal(TString& text, char what, char with, size_t from = 0); -size_t SubstGlobal(std::string& text, char what, char with, size_t from = 0); -size_t SubstGlobal(TUtf16String& text, wchar16 what, wchar16 with, size_t from = 0); -size_t SubstGlobal(std::u16string& text, wchar16 what, wchar16 with, size_t from = 0); +/* Replace all occurences of character `what` with character `with` starting from position `from`. + * + * @param text String to modify. + * @param what Character to replace. + * @param with Character to use as replacement. + * @param from Position at with to start replacement. + * + * @return Number of replacements occured. + */ +size_t SubstGlobal(TString& text, char what, char with, size_t from = 0); +size_t SubstGlobal(std::string& text, char what, char with, size_t from = 0); +size_t SubstGlobal(TUtf16String& text, wchar16 what, wchar16 with, size_t from = 0); +size_t SubstGlobal(std::u16string& text, wchar16 what, wchar16 with, size_t from = 0); size_t SubstGlobal(TUtf32String& text, wchar32 what, wchar32 with, size_t from = 0); -// TODO(yazevnul): -// - rename `SubstGlobal` to `ReplaceAll` for convenience +// TODO(yazevnul): +// - rename `SubstGlobal` to `ReplaceAll` for convenience // - add `SubstGlobalCopy(TStringBuf)` for convenience -// - add `RemoveAll(text, what, from)` as a shortcut for `SubstGlobal(text, what, "", from)` -// - rename file to `replace.h` +// - add `RemoveAll(text, what, from)` as a shortcut for `SubstGlobal(text, what, "", from)` +// - rename file to `replace.h` /* Replace all occurences of substring or character `what` with string or character `with` starting from position `from`, and return result string. * diff --git a/util/string/subst_ut.cpp b/util/string/subst_ut.cpp index fc88469ceb..21eccef779 100644 --- a/util/string/subst_ut.cpp +++ b/util/string/subst_ut.cpp @@ -4,7 +4,7 @@ #include <library/cpp/testing/unittest/registar.h> -Y_UNIT_TEST_SUITE(TStringSubst) { +Y_UNIT_TEST_SUITE(TStringSubst) { static const size_t MIN_FROM_CTX = 4; static const TVector<TString> ALL_FROM{TString("F"), TString("FF")}; static const TVector<TString> ALL_TO{TString(""), TString("T"), TString("TT"), TString("TTT")}; @@ -24,7 +24,7 @@ Y_UNIT_TEST_SUITE(TStringSubst) { } } - Y_UNIT_TEST(TestSubstGlobalNoSubstA) { + Y_UNIT_TEST(TestSubstGlobalNoSubstA) { for (const auto& from : ALL_FROM) { const size_t fromSz = from.size(); const size_t minSz = fromSz; @@ -40,7 +40,7 @@ Y_UNIT_TEST_SUITE(TStringSubst) { } } - Y_UNIT_TEST(TestSubstGlobalNoSubstB) { + Y_UNIT_TEST(TestSubstGlobalNoSubstB) { for (const auto& from : ALL_FROM) { const size_t fromSz = from.size(); const size_t minSz = fromSz; @@ -103,23 +103,23 @@ Y_UNIT_TEST_SUITE(TStringSubst) { } } - Y_UNIT_TEST(TestSubstGlobalSubst1) { + Y_UNIT_TEST(TestSubstGlobalSubst1) { DoTestSubstGlobal(1); } - Y_UNIT_TEST(TestSubstGlobalSubst2) { + Y_UNIT_TEST(TestSubstGlobalSubst2) { DoTestSubstGlobal(2); } - Y_UNIT_TEST(TestSubstGlobalSubst3) { + Y_UNIT_TEST(TestSubstGlobalSubst3) { DoTestSubstGlobal(3); } - Y_UNIT_TEST(TestSubstGlobalSubst4) { + Y_UNIT_TEST(TestSubstGlobalSubst4) { DoTestSubstGlobal(4); } - Y_UNIT_TEST(TestSubstGlobalOld) { + Y_UNIT_TEST(TestSubstGlobalOld) { TString s; s = "aaa"; SubstGlobal(s, "a", "bb"); @@ -160,7 +160,7 @@ Y_UNIT_TEST_SUITE(TStringSubst) { UNIT_ASSERT_EQUAL(s10, TString("Москва Париж")); } - Y_UNIT_TEST(TestSubstCharGlobal) { + Y_UNIT_TEST(TestSubstCharGlobal) { TUtf16String w = u"abcdabcd"; SubstGlobal(w, wchar16('b'), wchar16('B'), 3); UNIT_ASSERT_EQUAL(w, u"abcdaBcd"); @@ -180,74 +180,74 @@ Y_UNIT_TEST_SUITE(TStringSubst) { UNIT_ASSERT_EQUAL(s2, TString("abb")); } - Y_UNIT_TEST(TestSubstStdString) { + Y_UNIT_TEST(TestSubstStdString) { std::string s = "aaa"; SubstGlobal(s, "a", "b", 1); UNIT_ASSERT_EQUAL(s, "abb"); } - + Y_UNIT_TEST(TestSubstStdStringRet) { const std::string s1 = "aaa"; const std::string s2 = SubstGlobalCopy(s1, "a", "b", 1); UNIT_ASSERT_EQUAL(s2, "abb"); } - Y_UNIT_TEST(TestSubstGlobalChar) { - { + Y_UNIT_TEST(TestSubstGlobalChar) { + { const TString s = "a"; const TString st = "b"; TString ss = s; - UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b')); - UNIT_ASSERT_VALUES_EQUAL(st, ss); - } - { + UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b')); + UNIT_ASSERT_VALUES_EQUAL(st, ss); + } + { const TString s = "aa"; const TString st = "bb"; TString ss = s; - UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b')); - UNIT_ASSERT_VALUES_EQUAL(st, ss); - } - { + UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b')); + UNIT_ASSERT_VALUES_EQUAL(st, ss); + } + { const TString s = "aaa"; const TString st = "bbb"; TString ss = s; - UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b')); - UNIT_ASSERT_VALUES_EQUAL(st, ss); - } - { + UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b')); + UNIT_ASSERT_VALUES_EQUAL(st, ss); + } + { const TString s = "aaaa"; const TString st = "bbbb"; TString ss = s; - UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b')); - UNIT_ASSERT_VALUES_EQUAL(st, ss); - } - { + UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b')); + UNIT_ASSERT_VALUES_EQUAL(st, ss); + } + { const TString s = "aaaaa"; const TString st = "bbbbb"; TString ss = s; - UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b')); - UNIT_ASSERT_VALUES_EQUAL(st, ss); - } - { + UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b')); + UNIT_ASSERT_VALUES_EQUAL(st, ss); + } + { const TString s = "aaaaaa"; const TString st = "bbbbbb"; TString ss = s; - UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b')); - UNIT_ASSERT_VALUES_EQUAL(st, ss); - } - { + UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b')); + UNIT_ASSERT_VALUES_EQUAL(st, ss); + } + { const TString s = "aaaaaaa"; const TString st = "bbbbbbb"; TString ss = s; - UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b')); - UNIT_ASSERT_VALUES_EQUAL(st, ss); - } - { + UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b')); + UNIT_ASSERT_VALUES_EQUAL(st, ss); + } + { const TString s = "aaaaaaaa"; const TString st = "bbbbbbbb"; TString ss = s; - UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b')); - UNIT_ASSERT_VALUES_EQUAL(st, ss); - } - } + UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b')); + UNIT_ASSERT_VALUES_EQUAL(st, ss); + } + } } diff --git a/util/string/type.cpp b/util/string/type.cpp index 668b445afa..49671c02c2 100644 --- a/util/string/type.cpp +++ b/util/string/type.cpp @@ -24,11 +24,11 @@ static bool IsNumberT(const TStringType& s) noexcept { return std::all_of(s.begin(), s.end(), IsAsciiDigit<typename TStringType::value_type>); } -bool IsNumber(const TStringBuf s) noexcept { +bool IsNumber(const TStringBuf s) noexcept { return IsNumberT(s); } -bool IsNumber(const TWtringBuf s) noexcept { +bool IsNumber(const TWtringBuf s) noexcept { return IsNumberT(s); } @@ -41,11 +41,11 @@ static bool IsHexNumberT(const TStringType& s) noexcept { return std::all_of(s.begin(), s.end(), IsAsciiHex<typename TStringType::value_type>); } -bool IsHexNumber(const TStringBuf s) noexcept { +bool IsHexNumber(const TStringBuf s) noexcept { return IsHexNumberT(s); } -bool IsHexNumber(const TWtringBuf s) noexcept { +bool IsHexNumber(const TWtringBuf s) noexcept { return IsHexNumberT(s); } diff --git a/util/string/type_ut.cpp b/util/string/type_ut.cpp index 7f342a8e24..03e7af62bd 100644 --- a/util/string/type_ut.cpp +++ b/util/string/type_ut.cpp @@ -4,15 +4,15 @@ #include <util/charset/wide.h> -Y_UNIT_TEST_SUITE(TStringClassify) { - Y_UNIT_TEST(TestIsSpace) { +Y_UNIT_TEST_SUITE(TStringClassify) { + Y_UNIT_TEST(TestIsSpace) { UNIT_ASSERT_EQUAL(IsSpace(" "), true); UNIT_ASSERT_EQUAL(IsSpace("\t\r\n"), true); UNIT_ASSERT_EQUAL(IsSpace(""), false); UNIT_ASSERT_EQUAL(IsSpace(" a"), false); } - Y_UNIT_TEST(TestIsTrue) { + Y_UNIT_TEST(TestIsTrue) { UNIT_ASSERT(IsTrue("1")); UNIT_ASSERT(IsTrue("yes")); UNIT_ASSERT(IsTrue("YeS")); @@ -26,7 +26,7 @@ Y_UNIT_TEST_SUITE(TStringClassify) { UNIT_ASSERT(!IsTrue("foobar")); } - Y_UNIT_TEST(TestIsFalse) { + Y_UNIT_TEST(TestIsFalse) { UNIT_ASSERT(IsFalse("0")); UNIT_ASSERT(IsFalse("no")); UNIT_ASSERT(IsFalse("off")); @@ -39,7 +39,7 @@ Y_UNIT_TEST_SUITE(TStringClassify) { UNIT_ASSERT(!IsFalse("foobar")); } - Y_UNIT_TEST(TestIsNumber) { + Y_UNIT_TEST(TestIsNumber) { UNIT_ASSERT(IsNumber("0")); UNIT_ASSERT(IsNumber("12345678901234567890")); UNIT_ASSERT(!IsNumber("1234567890a")); @@ -54,7 +54,7 @@ Y_UNIT_TEST_SUITE(TStringClassify) { UNIT_ASSERT(!IsNumber(u"foobar")); } - Y_UNIT_TEST(TestIsHexNumber) { + Y_UNIT_TEST(TestIsHexNumber) { UNIT_ASSERT(IsHexNumber("0")); UNIT_ASSERT(IsHexNumber("aaaadddAAAAA")); UNIT_ASSERT(IsHexNumber("0123456789ABCDEFabcdef")); diff --git a/util/string/util.h b/util/string/util.h index 4c9732fcaf..0d77a5042b 100644 --- a/util/string/util.h +++ b/util/string/util.h @@ -132,7 +132,7 @@ public: /// strsep + remember character that was destroyed char* sep(char*& s, char& sep_char) const { if (!s) - return nullptr; + return nullptr; char* ret = s; char* next = brk(ret); if (*next) { @@ -141,7 +141,7 @@ public: s = next + 1; } else { sep_char = 0; - s = nullptr; + s = nullptr; } return ret; } diff --git a/util/string/util_ut.cpp b/util/string/util_ut.cpp index 706b63cfdc..18a2d8e195 100644 --- a/util/string/util_ut.cpp +++ b/util/string/util_ut.cpp @@ -20,7 +20,7 @@ public: UNIT_ASSERT_EQUAL(strcmp(rul.sep(s1), ""), 0); UNIT_ASSERT_EQUAL(strcmp(rul.sep(s1), "%^&"), 0); UNIT_ASSERT_EQUAL(strcmp(rul.sep(s1), "+-"), 0); - UNIT_ASSERT_EQUAL(rul.sep(s1), nullptr); + UNIT_ASSERT_EQUAL(rul.sep(s1), nullptr); } void TestRemoveAll() { @@ -35,7 +35,7 @@ public: {"hello world", 'x', "hello world"}, }; - for (const T* t = tests; t != std::end(tests); ++t) { + for (const T* t = tests; t != std::end(tests); ++t) { TString str(t->Str); RemoveAll(str, t->Ch); UNIT_ASSERT_EQUAL(t->Result, str); diff --git a/util/string/vector.h b/util/string/vector.h index fce7e4ab00..e36c348bbe 100644 --- a/util/string/vector.h +++ b/util/string/vector.h @@ -1,14 +1,14 @@ #pragma once -#include "cast.h" +#include "cast.h" #include "split.h" - + #include <util/generic/map.h> -#include <util/generic/strbuf.h> +#include <util/generic/strbuf.h> #include <util/generic/string.h> #include <util/generic/vector.h> #include <util/string/cast.h> -#include <util/system/yassert.h> +#include <util/system/yassert.h> #define KEEP_EMPTY_TOKENS 0x01 @@ -120,8 +120,8 @@ inline TString JoinVectorIntoString(const TVector<T>& v, size_t index, size_t co TUtf16String JoinStrings(const TVector<TUtf16String>& v, const TWtringBuf delim); TUtf16String JoinStrings(const TVector<TUtf16String>& v, size_t index, size_t count, const TWtringBuf delim); -//! Converts vector of strings to vector of type T variables -template <typename T, typename TStringType> +//! Converts vector of strings to vector of type T variables +template <typename T, typename TStringType> TVector<T> Scan(const TVector<TStringType>& input) { TVector<T> output; output.reserve(input.size()); diff --git a/util/string/vector_ut.cpp b/util/string/vector_ut.cpp index 9c4222f9ee..817120f268 100644 --- a/util/string/vector_ut.cpp +++ b/util/string/vector_ut.cpp @@ -4,14 +4,14 @@ #include "cast.h" #include "vector.h" -Y_UNIT_TEST_SUITE(TStringJoinTest) { - Y_UNIT_TEST(Test1) { +Y_UNIT_TEST_SUITE(TStringJoinTest) { + Y_UNIT_TEST(Test1) { TVector<TUtf16String> v; UNIT_ASSERT_EQUAL(JoinStrings(v, ToWtring("")), ToWtring("")); } - Y_UNIT_TEST(Test2) { + Y_UNIT_TEST(Test2) { TVector<TUtf16String> v; v.push_back(ToWtring("1")); @@ -20,7 +20,7 @@ Y_UNIT_TEST_SUITE(TStringJoinTest) { UNIT_ASSERT_EQUAL(JoinStrings(v, ToWtring(" ")), ToWtring("1 2")); } - Y_UNIT_TEST(Test3) { + Y_UNIT_TEST(Test3) { TVector<TUtf16String> v; v.push_back(ToWtring("1")); @@ -29,7 +29,7 @@ Y_UNIT_TEST_SUITE(TStringJoinTest) { UNIT_ASSERT_EQUAL(JoinStrings(v, 1, 10, ToWtring(" ")), ToWtring("2")); } - Y_UNIT_TEST(TestJoinWStrings) { + Y_UNIT_TEST(TestJoinWStrings) { const TUtf16String str = u"Яндекс"; const TVector<TUtf16String> v(1, str); |