diff --git a/libutils/String16.cpp b/libutils/String16.cpp index faf90c233..c42cada97 100644 --- a/libutils/String16.cpp +++ b/libutils/String16.cpp @@ -96,6 +96,12 @@ String16::String16(const String16& o) acquire(); } +String16::String16(String16&& o) noexcept + : mString(o.mString) +{ + o.mString = getEmptyString(); +} + String16::String16(const String16& o, size_t len, size_t begin) : mString(getEmptyString()) { @@ -126,6 +132,13 @@ String16::~String16() release(); } +String16& String16::operator=(String16&& other) noexcept { + release(); + mString = other.mString; + other.mString = getEmptyString(); + return *this; +} + size_t String16::size() const { if (isStaticString()) { diff --git a/libutils/String16_test.cpp b/libutils/String16_test.cpp index 54662ac41..917f1a3e6 100644 --- a/libutils/String16_test.cpp +++ b/libutils/String16_test.cpp @@ -64,6 +64,13 @@ TEST(String16Test, Move) { EXPECT_STR16EQ(u"Verify me", another); } +TEST(String16Test, MoveAssign) { + String16 tmp("Verify me"); + String16 another; + another = std::move(tmp); + EXPECT_STR16EQ(u"Verify me", another); +} + TEST(String16Test, Size) { String16 tmp("Verify me"); EXPECT_EQ(9U, tmp.size()); @@ -123,6 +130,10 @@ TEST(String16Test, StaticStringMove) { String16 another(std::move(tmp)); EXPECT_STR16EQ(u"Verify me", another); EXPECT_TRUE(another.isStaticString()); + // move/copy from StaticString16 is specialized (just copy the handle). + // no extra actions required. + EXPECT_STR16EQ(u"Verify me", tmp); + EXPECT_TRUE(tmp.isStaticString()); } TEST(String16Test, StaticStringSize) { @@ -174,10 +185,16 @@ TEST(String16Test, StringSetToStaticString) { EXPECT_STR16EQ(u"Verify me", another); } -TEST(String16Test, StringMoveFromStaticString) { +TEST(String16Test, StringMoveAssignFromStaticString) { StaticString16 tmp(u"Verify me"); - String16 another(std::move(tmp)); + String16 another(u"nonstatic"); + another = std::move(tmp); EXPECT_STR16EQ(u"Verify me", another); + EXPECT_TRUE(another.isStaticString()); + // move/copy from StaticString16 is specialized (just copy handle). + // no extra actions required. + EXPECT_STR16EQ(u"Verify me", tmp); + EXPECT_TRUE(tmp.isStaticString()); } TEST(String16Test, EmptyStringIsStatic) { diff --git a/libutils/include/utils/String16.h b/libutils/include/utils/String16.h index 60d523a4c..53f11fd72 100644 --- a/libutils/include/utils/String16.h +++ b/libutils/include/utils/String16.h @@ -41,6 +41,7 @@ class String16 public: String16(); String16(const String16& o); + String16(String16&& o) noexcept; String16(const String16& o, size_t len, size_t begin=0); @@ -69,6 +70,7 @@ public: status_t append(const char16_t* other, size_t len); inline String16& operator=(const String16& other); + String16& operator=(String16&& other) noexcept; inline String16& operator+=(const String16& other); inline String16 operator+(const String16& other) const; @@ -176,6 +178,12 @@ protected: public: template explicit constexpr String16(const StaticString16& s) : mString(s.mString) {} + template + constexpr String16& operator=(const StaticString16& s) { + release(); + mString = s.mString; + return *this; + } }; // String16 can be trivially moved using memcpy() because moving does not