Browse Source

Restoring authorship annotation for <marat-khalili@yandex-team.ru>. Commit 2 of 2.

marat-khalili 3 years ago
parent
commit
45d88ab625

+ 184 - 184
util/generic/benchmark/string/benchmarks.h

@@ -1,188 +1,188 @@
 #pragma once
 
-// Define BENCHMARK_PREFIX and BENCHMARKED_CLASS before including this file. 
- 
-#include <util/generic/xrange.h> 
- 
-#define Y_CPU_PREFIXED_BENCHMARK_HELPER(prefix, name, iface) Y_CPU_BENCHMARK(prefix##name, iface) 
-#define Y_CPU_PREFIXED_BENCHMARK(prefix, name, iface) Y_CPU_PREFIXED_BENCHMARK_HELPER(prefix, name, iface) 
-#define CONCATENATE3_HELPER(a, b, c) a##b##c 
-#define CONCATENATE3(a, b, c) CONCATENATE3_HELPER(a, b, c) 
- 
-namespace { 
-    namespace CONCATENATE3(N, BENCHMARK_PREFIX, Benchmark) { 
-        using TBenchmarkedClass = BENCHMARKED_CLASS; 
- 
-        const auto defaultString = TBenchmarkedClass(); 
-        const auto emptyString = TBenchmarkedClass(""); 
+// Define BENCHMARK_PREFIX and BENCHMARKED_CLASS before including this file.
+
+#include <util/generic/xrange.h>
+
+#define Y_CPU_PREFIXED_BENCHMARK_HELPER(prefix, name, iface) Y_CPU_BENCHMARK(prefix##name, iface)
+#define Y_CPU_PREFIXED_BENCHMARK(prefix, name, iface) Y_CPU_PREFIXED_BENCHMARK_HELPER(prefix, name, iface)
+#define CONCATENATE3_HELPER(a, b, c) a##b##c
+#define CONCATENATE3(a, b, c) CONCATENATE3_HELPER(a, b, c)
+
+namespace {
+    namespace CONCATENATE3(N, BENCHMARK_PREFIX, Benchmark) {
+        using TBenchmarkedClass = BENCHMARKED_CLASS;
+
+        const auto defaultString = TBenchmarkedClass();
+        const auto emptyString = TBenchmarkedClass("");
         const auto lengthOneString = TBenchmarkedClass("1");
         const auto length1KString = TBenchmarkedClass(1000, '1');
- 
-        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CreateDefault, iface) { 
-            for (const auto i : xrange(iface.Iterations())) { 
-                Y_UNUSED(i); 
-                auto result = TBenchmarkedClass(); 
-                Y_DO_NOT_OPTIMIZE_AWAY(result); 
-            } 
-        } 
- 
-        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CreateFromEmptyLiteral, iface) { 
-            for (const auto i : xrange(iface.Iterations())) { 
-                Y_UNUSED(i); 
-                auto result = TBenchmarkedClass(""); 
-                Y_DO_NOT_OPTIMIZE_AWAY(result); 
-            } 
-        } 
- 
-        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CreateFromLengthOneLiteral, iface) { 
-            for (const auto i : xrange(iface.Iterations())) { 
-                Y_UNUSED(i); 
-                auto result = TBenchmarkedClass("1"); 
-                Y_DO_NOT_OPTIMIZE_AWAY(result); 
-            } 
-        } 
- 
-        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CreateLength1K, iface) { 
-            for (const auto i : xrange(iface.Iterations())) { 
-                Y_UNUSED(i); 
-                auto result = TBenchmarkedClass(1000, '1'); 
-                Y_DO_NOT_OPTIMIZE_AWAY(result); 
-            } 
-        } 
- 
-        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyDefaultString, iface) { 
-            const auto& sourceString = defaultString; 
-            for (const auto i : xrange(iface.Iterations())) { 
-                Y_UNUSED(i); 
-                auto result = TBenchmarkedClass(sourceString); 
-                Y_DO_NOT_OPTIMIZE_AWAY(result); 
-            } 
-        } 
- 
-        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyEmptyString, iface) { 
-            const auto& sourceString = emptyString; 
-            for (const auto i : xrange(iface.Iterations())) { 
-                Y_UNUSED(i); 
-                auto result = TBenchmarkedClass(sourceString); 
-                Y_DO_NOT_OPTIMIZE_AWAY(result); 
-            } 
-        } 
- 
-        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyLengthOneString, iface) { 
-            const auto& sourceString = lengthOneString; 
-            for (const auto i : xrange(iface.Iterations())) { 
-                Y_UNUSED(i); 
-                auto result = TBenchmarkedClass(sourceString); 
-                Y_DO_NOT_OPTIMIZE_AWAY(result); 
-            } 
-        } 
- 
-        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyLength1KString, iface) { 
-            const auto& sourceString = length1KString; 
-            for (const auto i : xrange(iface.Iterations())) { 
-                Y_UNUSED(i); 
-                auto result = TBenchmarkedClass(sourceString); 
-                Y_DO_NOT_OPTIMIZE_AWAY(result); 
-            } 
-        } 
- 
-        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndUpdateLengthOneString, iface) { 
-            const auto& sourceString = lengthOneString; 
-            for (const auto i : xrange(iface.Iterations())) { 
-                Y_UNUSED(i); 
-                auto targetString = TBenchmarkedClass(sourceString); 
-                auto result = targetString[0] = '0'; 
-                Y_DO_NOT_OPTIMIZE_AWAY(targetString); 
-                Y_DO_NOT_OPTIMIZE_AWAY(result); 
-            } 
-        } 
- 
-        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndAppendDefaultString, iface) { 
-            const auto& sourceString = defaultString; 
-            const TBenchmarkedClass::size_type insertPosition = sourceString.size(); 
-            for (const auto i : xrange(iface.Iterations())) { 
-                Y_UNUSED(i); 
-                auto targetString = TBenchmarkedClass(sourceString); 
-                auto result = targetString.insert(insertPosition, 1, '0'); 
-                Y_DO_NOT_OPTIMIZE_AWAY(targetString); 
-                Y_DO_NOT_OPTIMIZE_AWAY(result); 
-            } 
-        } 
- 
-        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndAppendEmptyString, iface) { 
-            const auto& sourceString = emptyString; 
-            const TBenchmarkedClass::size_type insertPosition = sourceString.size(); 
-            for (const auto i : xrange(iface.Iterations())) { 
-                Y_UNUSED(i); 
-                auto targetString = TBenchmarkedClass(sourceString); 
-                auto result = targetString.insert(insertPosition, 1, '0'); 
-                Y_DO_NOT_OPTIMIZE_AWAY(targetString); 
-                Y_DO_NOT_OPTIMIZE_AWAY(result); 
-            } 
-        } 
- 
-        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndAppendLengthOneString, iface) { 
-            const auto& sourceString = lengthOneString; 
-            const TBenchmarkedClass::size_type insertPosition = sourceString.size(); 
-            for (const auto i : xrange(iface.Iterations())) { 
-                Y_UNUSED(i); 
-                auto targetString = TBenchmarkedClass(sourceString); 
-                auto result = targetString.insert(insertPosition, 1, '0'); 
-                Y_DO_NOT_OPTIMIZE_AWAY(targetString); 
-                Y_DO_NOT_OPTIMIZE_AWAY(result); 
-            } 
-        } 
- 
-        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndPrependLengthOneString, iface) { 
-            const auto& sourceString = lengthOneString; 
-            const TBenchmarkedClass::size_type insertPosition = 0; 
-            for (const auto i : xrange(iface.Iterations())) { 
-                Y_UNUSED(i); 
-                auto targetString = TBenchmarkedClass(sourceString); 
-                auto result = targetString.insert(insertPosition, 1, '0'); 
-                Y_DO_NOT_OPTIMIZE_AWAY(targetString); 
-                Y_DO_NOT_OPTIMIZE_AWAY(result); 
-            } 
-        } 
- 
-        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndUpdateLength1KString, iface) { 
-            const auto& sourceString = length1KString; 
-            for (const auto i : xrange(iface.Iterations())) { 
-                Y_UNUSED(i); 
-                auto targetString = TBenchmarkedClass(sourceString); 
-                auto result = targetString[0] = '0'; 
-                Y_DO_NOT_OPTIMIZE_AWAY(targetString); 
-                Y_DO_NOT_OPTIMIZE_AWAY(result); 
-            } 
-        } 
- 
-        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndAppendLength1KString, iface) { 
-            const auto& sourceString = length1KString; 
-            const TBenchmarkedClass::size_type insertPosition = sourceString.size(); 
-            for (const auto i : xrange(iface.Iterations())) { 
-                Y_UNUSED(i); 
-                auto targetString = TBenchmarkedClass(sourceString); 
-                auto result = targetString.insert(insertPosition, 1, '0'); 
-                Y_DO_NOT_OPTIMIZE_AWAY(targetString); 
-                Y_DO_NOT_OPTIMIZE_AWAY(result); 
-            } 
-        } 
- 
-        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndPrependLength1KString, iface) { 
-            const auto& sourceString = length1KString; 
-            const TBenchmarkedClass::size_type insertPosition = 0; 
-            for (const auto i : xrange(iface.Iterations())) { 
-                Y_UNUSED(i); 
-                auto targetString = TBenchmarkedClass(sourceString); 
-                auto result = targetString.insert(insertPosition, 1, '0'); 
-                Y_DO_NOT_OPTIMIZE_AWAY(targetString); 
-                Y_DO_NOT_OPTIMIZE_AWAY(result); 
-            } 
-        } 
-    } 
-} 
- 
-#undef CONCATENATE3 
-#undef CONCATENATE3_HELPER 
-#undef Y_CPU_PREFIXED_BENCHMARK 
-#undef Y_CPU_PREFIXED_BENCHMARK_HELPER 
+
+        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CreateDefault, iface) {
+            for (const auto i : xrange(iface.Iterations())) {
+                Y_UNUSED(i);
+                auto result = TBenchmarkedClass();
+                Y_DO_NOT_OPTIMIZE_AWAY(result);
+            }
+        }
+
+        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CreateFromEmptyLiteral, iface) {
+            for (const auto i : xrange(iface.Iterations())) {
+                Y_UNUSED(i);
+                auto result = TBenchmarkedClass("");
+                Y_DO_NOT_OPTIMIZE_AWAY(result);
+            }
+        }
+
+        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CreateFromLengthOneLiteral, iface) {
+            for (const auto i : xrange(iface.Iterations())) {
+                Y_UNUSED(i);
+                auto result = TBenchmarkedClass("1");
+                Y_DO_NOT_OPTIMIZE_AWAY(result);
+            }
+        }
+
+        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CreateLength1K, iface) {
+            for (const auto i : xrange(iface.Iterations())) {
+                Y_UNUSED(i);
+                auto result = TBenchmarkedClass(1000, '1');
+                Y_DO_NOT_OPTIMIZE_AWAY(result);
+            }
+        }
+
+        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyDefaultString, iface) {
+            const auto& sourceString = defaultString;
+            for (const auto i : xrange(iface.Iterations())) {
+                Y_UNUSED(i);
+                auto result = TBenchmarkedClass(sourceString);
+                Y_DO_NOT_OPTIMIZE_AWAY(result);
+            }
+        }
+
+        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyEmptyString, iface) {
+            const auto& sourceString = emptyString;
+            for (const auto i : xrange(iface.Iterations())) {
+                Y_UNUSED(i);
+                auto result = TBenchmarkedClass(sourceString);
+                Y_DO_NOT_OPTIMIZE_AWAY(result);
+            }
+        }
+
+        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyLengthOneString, iface) {
+            const auto& sourceString = lengthOneString;
+            for (const auto i : xrange(iface.Iterations())) {
+                Y_UNUSED(i);
+                auto result = TBenchmarkedClass(sourceString);
+                Y_DO_NOT_OPTIMIZE_AWAY(result);
+            }
+        }
+
+        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyLength1KString, iface) {
+            const auto& sourceString = length1KString;
+            for (const auto i : xrange(iface.Iterations())) {
+                Y_UNUSED(i);
+                auto result = TBenchmarkedClass(sourceString);
+                Y_DO_NOT_OPTIMIZE_AWAY(result);
+            }
+        }
+
+        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndUpdateLengthOneString, iface) {
+            const auto& sourceString = lengthOneString;
+            for (const auto i : xrange(iface.Iterations())) {
+                Y_UNUSED(i);
+                auto targetString = TBenchmarkedClass(sourceString);
+                auto result = targetString[0] = '0';
+                Y_DO_NOT_OPTIMIZE_AWAY(targetString);
+                Y_DO_NOT_OPTIMIZE_AWAY(result);
+            }
+        }
+
+        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndAppendDefaultString, iface) {
+            const auto& sourceString = defaultString;
+            const TBenchmarkedClass::size_type insertPosition = sourceString.size();
+            for (const auto i : xrange(iface.Iterations())) {
+                Y_UNUSED(i);
+                auto targetString = TBenchmarkedClass(sourceString);
+                auto result = targetString.insert(insertPosition, 1, '0');
+                Y_DO_NOT_OPTIMIZE_AWAY(targetString);
+                Y_DO_NOT_OPTIMIZE_AWAY(result);
+            }
+        }
+
+        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndAppendEmptyString, iface) {
+            const auto& sourceString = emptyString;
+            const TBenchmarkedClass::size_type insertPosition = sourceString.size();
+            for (const auto i : xrange(iface.Iterations())) {
+                Y_UNUSED(i);
+                auto targetString = TBenchmarkedClass(sourceString);
+                auto result = targetString.insert(insertPosition, 1, '0');
+                Y_DO_NOT_OPTIMIZE_AWAY(targetString);
+                Y_DO_NOT_OPTIMIZE_AWAY(result);
+            }
+        }
+
+        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndAppendLengthOneString, iface) {
+            const auto& sourceString = lengthOneString;
+            const TBenchmarkedClass::size_type insertPosition = sourceString.size();
+            for (const auto i : xrange(iface.Iterations())) {
+                Y_UNUSED(i);
+                auto targetString = TBenchmarkedClass(sourceString);
+                auto result = targetString.insert(insertPosition, 1, '0');
+                Y_DO_NOT_OPTIMIZE_AWAY(targetString);
+                Y_DO_NOT_OPTIMIZE_AWAY(result);
+            }
+        }
+
+        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndPrependLengthOneString, iface) {
+            const auto& sourceString = lengthOneString;
+            const TBenchmarkedClass::size_type insertPosition = 0;
+            for (const auto i : xrange(iface.Iterations())) {
+                Y_UNUSED(i);
+                auto targetString = TBenchmarkedClass(sourceString);
+                auto result = targetString.insert(insertPosition, 1, '0');
+                Y_DO_NOT_OPTIMIZE_AWAY(targetString);
+                Y_DO_NOT_OPTIMIZE_AWAY(result);
+            }
+        }
+
+        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndUpdateLength1KString, iface) {
+            const auto& sourceString = length1KString;
+            for (const auto i : xrange(iface.Iterations())) {
+                Y_UNUSED(i);
+                auto targetString = TBenchmarkedClass(sourceString);
+                auto result = targetString[0] = '0';
+                Y_DO_NOT_OPTIMIZE_AWAY(targetString);
+                Y_DO_NOT_OPTIMIZE_AWAY(result);
+            }
+        }
+
+        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndAppendLength1KString, iface) {
+            const auto& sourceString = length1KString;
+            const TBenchmarkedClass::size_type insertPosition = sourceString.size();
+            for (const auto i : xrange(iface.Iterations())) {
+                Y_UNUSED(i);
+                auto targetString = TBenchmarkedClass(sourceString);
+                auto result = targetString.insert(insertPosition, 1, '0');
+                Y_DO_NOT_OPTIMIZE_AWAY(targetString);
+                Y_DO_NOT_OPTIMIZE_AWAY(result);
+            }
+        }
+
+        Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndPrependLength1KString, iface) {
+            const auto& sourceString = length1KString;
+            const TBenchmarkedClass::size_type insertPosition = 0;
+            for (const auto i : xrange(iface.Iterations())) {
+                Y_UNUSED(i);
+                auto targetString = TBenchmarkedClass(sourceString);
+                auto result = targetString.insert(insertPosition, 1, '0');
+                Y_DO_NOT_OPTIMIZE_AWAY(targetString);
+                Y_DO_NOT_OPTIMIZE_AWAY(result);
+            }
+        }
+    }
+}
+
+#undef CONCATENATE3
+#undef CONCATENATE3_HELPER
+#undef Y_CPU_PREFIXED_BENCHMARK
+#undef Y_CPU_PREFIXED_BENCHMARK_HELPER

+ 8 - 8
util/generic/benchmark/string/std_string.cpp

@@ -1,8 +1,8 @@
-#include <library/cpp/testing/benchmark/bench.h> 
- 
-#include <string> 
- 
-#define BENCHMARK_PREFIX StdString 
-#define BENCHMARKED_CLASS std::string 
- 
-#include "benchmarks.h" 
+#include <library/cpp/testing/benchmark/bench.h>
+
+#include <string>
+
+#define BENCHMARK_PREFIX StdString
+#define BENCHMARKED_CLASS std::string
+
+#include "benchmarks.h"

+ 8 - 8
util/generic/benchmark/string/string.cpp

@@ -1,8 +1,8 @@
-#include <library/cpp/testing/benchmark/bench.h> 
- 
-#include <util/generic/string.h> 
- 
-#define BENCHMARK_PREFIX TString 
-#define BENCHMARKED_CLASS ::TString 
- 
-#include "benchmarks.h" 
+#include <library/cpp/testing/benchmark/bench.h>
+
+#include <util/generic/string.h>
+
+#define BENCHMARK_PREFIX TString
+#define BENCHMARKED_CLASS ::TString
+
+#include "benchmarks.h"

+ 11 - 11
util/generic/benchmark/string/ya.make

@@ -1,11 +1,11 @@
-Y_BENCHMARK() 
- 
-OWNER(g:util) 
-SUBSCRIBER(g:util-subscribers) 
- 
-SRCS( 
-    string.cpp 
-    std_string.cpp 
-) 
- 
-END() 
+Y_BENCHMARK()
+
+OWNER(g:util)
+SUBSCRIBER(g:util-subscribers)
+
+SRCS(
+    string.cpp
+    std_string.cpp
+)
+
+END()

+ 1 - 1
util/generic/benchmark/ya.make

@@ -12,7 +12,7 @@ RECURSE(
     singleton
     smart_pointers
     sort
-    string 
+    string
     vector_count_ctor
     vector_count_ctor/metrics
     cont_speed

+ 1 - 1
util/generic/string.cpp

@@ -1,7 +1,7 @@
 #include "string.h"
 
 #include <util/string/ascii.h>
-#include <util/system/sanitizers.h> 
+#include <util/system/sanitizers.h>
 #include <util/system/sys_alloc.h>
 #include <util/charset/wide.h>
 

+ 1 - 1
util/generic/string.h

@@ -127,7 +127,7 @@ public:
     }
 
     TBasicCharRef& operator=(TChar c) {
-        Y_ASSERT(Pos_ < S_.size() || (Pos_ == S_.size() && !c)); 
+        Y_ASSERT(Pos_ < S_.size() || (Pos_ == S_.size() && !c));
 
         S_.Detach()[Pos_] = c;
 

+ 67 - 67
util/generic/string_ut.cpp

@@ -294,67 +294,67 @@ protected:
         // End of block B
     }
 
-    void null_char_of_empty() { 
-        const TStringType s; 
- 
-        UNIT_ASSERT(s[s.size()] == 0); 
-    } 
- 
+    void null_char_of_empty() {
+        const TStringType s;
+
+        UNIT_ASSERT(s[s.size()] == 0);
+    }
+
     void null_char() {
         // ISO/IEC 14882:1998(E), ISO/IEC 14882:2003(E), 21.3.4 ('... the const version')
         const TStringType s(Data_._123456());
 
         UNIT_ASSERT(s[s.size()] == 0);
-    } 
-
-    // Allowed since C++17, see http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2475 
-    void null_char_assignment_to_subscript_of_empty() { 
-        TStringType s; 
- 
-#ifdef TSTRING_IS_STD_STRING 
-        using reference = volatile typename TStringType::value_type&; 
-#else 
-        using reference = typename TStringType::reference; 
+    }
+
+    // Allowed since C++17, see http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2475
+    void null_char_assignment_to_subscript_of_empty() {
+        TStringType s;
+
+#ifdef TSTRING_IS_STD_STRING
+        using reference = volatile typename TStringType::value_type&;
+#else
+        using reference = typename TStringType::reference;
 #endif
-        reference trailing_zero = s[s.size()]; 
-        trailing_zero = 0; 
-        UNIT_ASSERT(trailing_zero == 0); 
+        reference trailing_zero = s[s.size()];
+        trailing_zero = 0;
+        UNIT_ASSERT(trailing_zero == 0);
     }
 
-    // Allowed since C++17, see http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2475 
-    void null_char_assignment_to_subscript_of_nonempty() { 
-        TStringType s(Data_._123456()); 
- 
-#ifdef TSTRING_IS_STD_STRING 
-        using reference = volatile typename TStringType::value_type&; 
-#else 
-        using reference = typename TStringType::reference; 
-#endif 
-        reference trailing_zero = s[s.size()]; 
-        trailing_zero = 0; 
-        UNIT_ASSERT(trailing_zero == 0); 
-    } 
- 
-#ifndef TSTRING_IS_STD_STRING 
-    // Dereferencing string end() is not allowed by C++ standard as of C++20, avoid using in real code. 
-    void null_char_assignment_to_end_of_empty() { 
-        TStringType s; 
- 
-        volatile auto& trailing_zero = *(s.begin() + s.size()); 
-        trailing_zero = 0; 
-        UNIT_ASSERT(trailing_zero == 0); 
-    } 
- 
-    // Dereferencing string end() is not allowed by C++ standard as of C++20, avoid using in real code. 
-    void null_char_assignment_to_end_of_nonempty() { 
-        TStringType s(Data_._123456()); 
- 
-        volatile auto& trailing_zero = *(s.begin() + s.size()); 
-        trailing_zero = 0; 
-        UNIT_ASSERT(trailing_zero == 0); 
-    } 
-#endif 
- 
+    // Allowed since C++17, see http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2475
+    void null_char_assignment_to_subscript_of_nonempty() {
+        TStringType s(Data_._123456());
+
+#ifdef TSTRING_IS_STD_STRING
+        using reference = volatile typename TStringType::value_type&;
+#else
+        using reference = typename TStringType::reference;
+#endif
+        reference trailing_zero = s[s.size()];
+        trailing_zero = 0;
+        UNIT_ASSERT(trailing_zero == 0);
+    }
+
+#ifndef TSTRING_IS_STD_STRING
+    // Dereferencing string end() is not allowed by C++ standard as of C++20, avoid using in real code.
+    void null_char_assignment_to_end_of_empty() {
+        TStringType s;
+
+        volatile auto& trailing_zero = *(s.begin() + s.size());
+        trailing_zero = 0;
+        UNIT_ASSERT(trailing_zero == 0);
+    }
+
+    // Dereferencing string end() is not allowed by C++ standard as of C++20, avoid using in real code.
+    void null_char_assignment_to_end_of_nonempty() {
+        TStringType s(Data_._123456());
+
+        volatile auto& trailing_zero = *(s.begin() + s.size());
+        trailing_zero = 0;
+        UNIT_ASSERT(trailing_zero == 0);
+    }
+#endif
+
     void insert() {
         TStringType strorg = Data_.This_is_test_string_for_string_calls();
         TStringType str;
@@ -1114,14 +1114,14 @@ public:
     UNIT_TEST(erase);
     UNIT_TEST(data);
     UNIT_TEST(c_str);
-    UNIT_TEST(null_char_of_empty); 
+    UNIT_TEST(null_char_of_empty);
     UNIT_TEST(null_char);
-    UNIT_TEST(null_char_assignment_to_subscript_of_empty); 
-    UNIT_TEST(null_char_assignment_to_subscript_of_nonempty); 
-#ifndef TSTRING_IS_STD_STRING 
-    UNIT_TEST(null_char_assignment_to_end_of_empty); 
-    UNIT_TEST(null_char_assignment_to_end_of_nonempty); 
-#endif 
+    UNIT_TEST(null_char_assignment_to_subscript_of_empty);
+    UNIT_TEST(null_char_assignment_to_subscript_of_nonempty);
+#ifndef TSTRING_IS_STD_STRING
+    UNIT_TEST(null_char_assignment_to_end_of_empty);
+    UNIT_TEST(null_char_assignment_to_end_of_nonempty);
+#endif
     UNIT_TEST(insert);
     UNIT_TEST(resize);
     UNIT_TEST(find);
@@ -1150,14 +1150,14 @@ public:
     UNIT_TEST(erase);
     UNIT_TEST(data);
     UNIT_TEST(c_str);
-    UNIT_TEST(null_char_of_empty); 
+    UNIT_TEST(null_char_of_empty);
     UNIT_TEST(null_char);
-    UNIT_TEST(null_char_assignment_to_subscript_of_empty); 
-    UNIT_TEST(null_char_assignment_to_subscript_of_nonempty); 
-#ifndef TSTRING_IS_STD_STRING 
-    UNIT_TEST(null_char_assignment_to_end_of_empty); 
-    UNIT_TEST(null_char_assignment_to_end_of_nonempty); 
-#endif 
+    UNIT_TEST(null_char_assignment_to_subscript_of_empty);
+    UNIT_TEST(null_char_assignment_to_subscript_of_nonempty);
+#ifndef TSTRING_IS_STD_STRING
+    UNIT_TEST(null_char_assignment_to_end_of_empty);
+    UNIT_TEST(null_char_assignment_to_end_of_nonempty);
+#endif
     UNIT_TEST(insert);
     UNIT_TEST(resize);
     UNIT_TEST(find);

+ 11 - 11
util/system/sanitizers.cpp

@@ -123,20 +123,20 @@ void TFiberContext::AfterStart() noexcept {
     __sanitizer_finish_switch_fiber(nullptr, nullptr, nullptr);
 #endif
 }
- 
-#if defined(_tsan_enabled_) 
-extern "C" { 
-    // This function should not be directly exposed in headers 
-    // due to signature variations among contrib headers. 
+
+#if defined(_tsan_enabled_)
+extern "C" {
+    // This function should not be directly exposed in headers
+    // due to signature variations among contrib headers.
     void AnnotateBenignRaceSized(const char* file, int line,
                                  const volatile void* address,
-                                 size_t size, 
+                                 size_t size,
                                  const char* description);
-} 
+}
 void NSan::AnnotateBenignRaceSized(const char* file, int line,
                                    const volatile void* address,
-                                   size_t size, 
+                                   size_t size,
                                    const char* description) noexcept {
-    ::AnnotateBenignRaceSized(file, line, address, size, description); 
-} 
-#endif 
+    ::AnnotateBenignRaceSized(file, line, address, size, description);
+}
+#endif

+ 13 - 13
util/system/sanitizers.h

@@ -119,23 +119,23 @@ namespace NSan {
         Y_UNUSED(ptr);
 #endif
     }
- 
-#if defined(_tsan_enabled_) 
-    // defined in .cpp to avoid exposing problematic C-linkage version of AnnotateBenignRaceSized(...) 
+
+#if defined(_tsan_enabled_)
+    // defined in .cpp to avoid exposing problematic C-linkage version of AnnotateBenignRaceSized(...)
     void AnnotateBenignRaceSized(const char* file, int line,
                                  const volatile void* address,
-                                 size_t size, 
+                                 size_t size,
                                  const char* description) noexcept;
-#else 
+#else
     inline static void AnnotateBenignRaceSized(const char* file, int line,
                                                const volatile void* address,
-                                               size_t size, 
+                                               size_t size,
                                                const char* description) noexcept {
-        Y_UNUSED(file); 
-        Y_UNUSED(line); 
-        Y_UNUSED(address); 
-        Y_UNUSED(size); 
-        Y_UNUSED(description); 
-    } 
-#endif 
+        Y_UNUSED(file);
+        Y_UNUSED(line);
+        Y_UNUSED(address);
+        Y_UNUSED(size);
+        Y_UNUSED(description);
+    }
+#endif
 }