Utils: Make take of SmallString explicit

Using a value after the move is undefined. For example, if you move an
integer, it is not set to zero after the move. So you have to initialize
it again. Adding the take method to SmallString makes this explicit.
So if there is a case that you want to use the string again after
a move, use take or initialize it yourself.

Change-Id: I174116df9639d6a3f63c6f2c2a3bd184852927ce
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2022-07-30 15:50:06 +02:00
parent a91e6bd46c
commit 8a0f7db8eb
2 changed files with 30 additions and 8 deletions

View File

@@ -195,17 +195,17 @@ public:
BasicSmallString &operator=(BasicSmallString &&other) noexcept BasicSmallString &operator=(BasicSmallString &&other) noexcept
{ {
if (this == &other) swap(*this, other);
return *this;
this->~BasicSmallString();
m_data = std::move(other.m_data);
other.m_data.reset();
return *this; return *this;
} }
BasicSmallString take() noexcept
{
auto tmp = std::move(*this);
return tmp;
}
BasicSmallString clone() const BasicSmallString clone() const
{ {
BasicSmallString clonedString(m_data); BasicSmallString clonedString(m_data);

View File

@@ -1560,7 +1560,7 @@ TEST(SmallString, ShortSmallStringMoveAssignment)
copy = std::move(text); copy = std::move(text);
ASSERT_THAT(text, IsEmpty()); ASSERT_THAT(text, SmallString("more text"));
ASSERT_THAT(copy, SmallString("text")); ASSERT_THAT(copy, SmallString("text"));
} }
@@ -1571,6 +1571,28 @@ TEST(SmallString, LongSmallStringMoveAssignment)
copy = std::move(text); copy = std::move(text);
ASSERT_THAT(text, SmallString("more text"));
ASSERT_THAT(copy, SmallString("this is a very very very very long text"));
}
TEST(SmallString, ShortSmallStringTake)
{
SmallString text("text");
SmallString copy("more text");
copy = text.take();
ASSERT_THAT(text, IsEmpty());
ASSERT_THAT(copy, SmallString("text"));
}
TEST(SmallString, LongSmallStringTake)
{
SmallString text("this is a very very very very long text");
SmallString copy("more text");
copy = text.take();
ASSERT_THAT(text, IsEmpty()); ASSERT_THAT(text, IsEmpty());
ASSERT_THAT(copy, SmallString("this is a very very very very long text")); ASSERT_THAT(copy, SmallString("this is a very very very very long text"));
} }