aboutsummaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
authorswarmer <swarmer@yandex-team.com>2024-03-21 23:45:15 +0300
committerswarmer <swarmer@yandex-team.com>2024-03-21 23:55:53 +0300
commit120d7867596b83d6d954905dabd53fa97bfcdabf (patch)
tree322f65a5ffcef1ae28191b52b94d8e0e50e090e9 /util
parent37b755e3bb7576698ab37070517fbaecf6e7fd54 (diff)
downloadydb-120d7867596b83d6d954905dabd53fa97bfcdabf.tar.gz
movable TStringStream
Do not copy the internal string buffer in move constructors and the move assignment operator. 19e6948ae4706272838bc76831b9ff2051a20590
Diffstat (limited to 'util')
-rw-r--r--util/stream/str.h35
-rw-r--r--util/stream/str_ut.cpp35
2 files changed, 68 insertions, 2 deletions
diff --git a/util/stream/str.h b/util/stream/str.h
index 028bd572c0..1316dba800 100644
--- a/util/stream/str.h
+++ b/util/stream/str.h
@@ -125,6 +125,13 @@ public:
{
}
+ inline TStringStream(TString&& string)
+ : TEmbeddedString(std::move(string))
+ , TStringInput(*TEmbeddedString::Ptr())
+ , TStringOutput(*TEmbeddedString::Ptr())
+ {
+ }
+
inline TStringStream(const TStringStream& other)
: TEmbeddedString(other.Str())
, TStringInput(*TEmbeddedString::Ptr())
@@ -132,6 +139,14 @@ public:
{
}
+ inline TStringStream(TStringStream&& other)
+ : TEmbeddedString(std::move(other).Str())
+ , TStringInput(*TEmbeddedString::Ptr())
+ , TStringOutput(*TEmbeddedString::Ptr())
+ {
+ other.Pos_ = 0;
+ }
+
inline TStringStream& operator=(const TStringStream& other) {
// All references remain alive, we need to change position only
Str() = other.Str();
@@ -140,6 +155,15 @@ public:
return *this;
}
+ inline TStringStream& operator=(TStringStream&& other) {
+ // All references remain alive, we need to change position only
+ Str() = std::move(other).Str();
+ Pos_ = other.Pos_;
+ other.Pos_ = 0;
+
+ return *this;
+ }
+
~TStringStream() override;
/**
@@ -152,18 +176,25 @@ public:
/**
* @returns String that this stream is writing into.
*/
- inline TString& Str() noexcept {
+ inline TString& Str() & noexcept {
return *Ptr();
}
/**
* @returns String that this stream is writing into.
*/
- inline const TString& Str() const noexcept {
+ inline const TString& Str() const& noexcept {
return *Ptr();
}
/**
+ * @returns String that this stream is writing into.
+ */
+ inline TString&& Str() && noexcept {
+ return std::move(*Ptr());
+ }
+
+ /**
* @returns Pointer to the character data contained
* in this stream. The data is guaranteed
* to be null-terminated.
diff --git a/util/stream/str_ut.cpp b/util/stream/str_ut.cpp
index 534b58d71c..c5ab9ca5e9 100644
--- a/util/stream/str_ut.cpp
+++ b/util/stream/str_ut.cpp
@@ -2,6 +2,7 @@
#include <library/cpp/testing/unittest/registar.h>
#include <util/generic/typetraits.h>
+#include <util/string/join.h>
template <typename T>
const T ReturnConstTemp();
@@ -150,6 +151,40 @@ Y_UNIT_TEST_SUITE(TStringInputOutputTest) {
output1 << "baz";
}
+ Y_UNIT_TEST(MoveableStringInputStream) {
+ TString data{JoinSeq("\n", "qwertyuiop"sv)};
+ TStringInput in0{data};
+ TString str;
+ in0 >> str;
+ UNIT_ASSERT_VALUES_EQUAL(str, ToString(int('q')));
+ TStringInput in1{std::move(in0)};
+ in1 >> str;
+ UNIT_ASSERT_VALUES_EQUAL(str, ToString(int('w')));
+
+ // Check old stream is in a valid state
+ in0 >> str;
+ }
+
+ Y_UNIT_TEST(MoveableStringStream) {
+ TString str;
+ str.reserve(500);
+ const char* ptr = str.data();
+ TStringStream stream{std::move(str)};
+ stream << "foo"
+ << "bar";
+ TString out = std::move(stream).Str();
+ UNIT_ASSERT_EQUAL(ptr, out.data());
+ UNIT_ASSERT_STRINGS_EQUAL(out, "foobar");
+
+ TStringStream multiline{JoinSeq("\n", "qwertyuiop"sv)};
+ multiline >> str;
+ UNIT_ASSERT_VALUES_EQUAL(str, ToString(int('q')));
+ TStringStream other = std::move(multiline);
+ // Check old stream is in a valid state
+ multiline >> str;
+ multiline << "bar";
+ }
+
// There is no distinct tests for Out<> via IOutputStream.
// Let's tests strings output here.
Y_UNIT_TEST(TestWritingWideStrings) {