aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorswarmer <swarmer@yandex-team.com>2024-09-24 19:17:22 +0300
committerswarmer <swarmer@yandex-team.com>2024-09-24 19:32:50 +0300
commitd227fe5facffd839a1fe99cff97a904a05988705 (patch)
treea1023eaffd154db24e6a57bc9466afffc5df4196
parent917e7a21f4f924e2528852722e9c830002498b97 (diff)
downloadydb-d227fe5facffd839a1fe99cff97a904a05988705.tar.gz
faster implicit `TString` → `const std::string&` conversion: using template operator TStringType& to deprioritize non-const method
Converting a `TString` to a `const std::string&` should not cause data cloning. commit_hash:df425bd56f8517d882444e15f3cc586af92d90b3
-rw-r--r--util/generic/string.h3
-rw-r--r--util/generic/string_ut.cpp12
2 files changed, 14 insertions, 1 deletions
diff --git a/util/generic/string.h b/util/generic/string.h
index bbe340781a..3476f71b68 100644
--- a/util/generic/string.h
+++ b/util/generic/string.h
@@ -861,7 +861,8 @@ public:
return this->ConstRef();
}
- operator TStringType&() & {
+ template <typename T, typename = std::enable_if_t<std::is_same_v<T, TStringType>>>
+ operator T&() & {
return this->MutRef();
}
diff --git a/util/generic/string_ut.cpp b/util/generic/string_ut.cpp
index bfd86bb07e..01c7a01188 100644
--- a/util/generic/string_ut.cpp
+++ b/util/generic/string_ut.cpp
@@ -1243,4 +1243,16 @@ Y_UNIT_TEST_SUITE(Interop) {
Y_UNIT_TEST(TestTemp) {
UNIT_ASSERT_VALUES_EQUAL("x" + ConstRef(TString("y")), "xy");
}
+
+ static void ComparePointers(const std::string& s, const void* expected, TStringBuf descr) {
+ UNIT_ASSERT_VALUES_EQUAL_C(static_cast<const void*>(s.c_str()), expected, descr);
+ }
+
+ Y_UNIT_TEST(TestConstShared) {
+ TString s(600, 'a');
+ const void* stringStart = s.c_str();
+ ComparePointers(s, stringStart, "unique");
+ TString shared{s};
+ ComparePointers(s, stringStart, "shared"); // converting a TString to a `const std::string&` should not cause data cloning
+ }
} // Y_UNIT_TEST_SUITE(Interop)