[heap] introduce Move() and unify TakeFrom() for move semantics (#11972)

This change enhances the move semantics for heap-allocated container
classes (`Array`, `Data`, and `String`) by introducing a consistent
pattern.

A new `Move()` method is added to `Heap::Array`, `Heap::Data`, and
`Heap::String`. This method returns an rvalue reference to the object,
making the intent to transfer ownership explicit at the call site.

The existing `TakeFrom()` methods are updated to accept an rvalue
reference and now include a check to prevent self-assignment, which
improves robustness.

For consistency, `Heap::Data::SetFrom(Data&&)` and
`Heap::String::Set(String&&)` are renamed to `TakeFrom()`.

All call sites are updated to use the new `foo.TakeFrom(bar.Move())`
pattern, replacing the more verbose and less clear
`static_cast<...&&>(bar)`.

Unit tests are updated to validate the new `TakeFrom()` and `Move()`
semantics, including tests for self-assignment and moving from a
null (empty) container
This commit is contained in:
Abtin Keshavarzian
2025-09-29 18:04:56 -07:00
committed by GitHub
parent fb6fa2002a
commit 14373d5543
10 changed files with 145 additions and 44 deletions
+43 -1
View File
@@ -139,6 +139,27 @@ void TestHeapString(void)
SuccessOrQuit(str1.Set(GetName()), "Set() with move semantics failed");
VerifyString("str1", str1, "name");
printf("------------------------------------------------------------------------------------\n");
printf("TakeFrom() and Move()\n\n");
SuccessOrQuit(str1.Set("string to be moved"));
str2.Free();
VerifyString("str1", str1, "string to be moved");
VerifyString("str2", str2, nullptr);
str2.TakeFrom(str1.Move());
VerifyString("str1", str1, nullptr);
VerifyString("str2", str2, "string to be moved");
// Test moving from self
str2.TakeFrom(str2.Move());
VerifyString("str2", str2, "string to be moved");
// Test moving a null string
str2.TakeFrom(str1.Move());
VerifyString("str1", str1, nullptr);
VerifyString("str2", str2, nullptr);
printf("------------------------------------------------------------------------------------\n");
printf("operator==() with two null string\n\n");
str1.Free();
@@ -208,6 +229,7 @@ void TestHeapData(void)
MessagePool *messagePool;
Message *message;
Heap::Data data;
Heap::Data data2;
uint16_t offset;
const uint8_t *oldBuffer;
@@ -314,9 +336,29 @@ void TestHeapData(void)
printf("------------------------------------------------------------------------------------\n");
printf("SetFrom() move semantics\n\n");
data.SetFrom(GetData());
data.TakeFrom(GetData().Move());
VerifyData(data, &kTestValue, sizeof(kTestValue));
printf("------------------------------------------------------------------------------------\n");
printf("TakeFrom() and Move()\n\n");
SuccessOrQuit(data.SetFrom(kData1, sizeof(kData1)));
VerifyData(data, kData1);
VerifyData(data2, nullptr, 0);
data2.TakeFrom(data.Move());
VerifyData(data, nullptr, 0);
VerifyData(data2, kData1);
// Test moving from self
data2.TakeFrom(data2.Move());
VerifyData(data2, kData1);
// Test moving a null data
data2.TakeFrom(data.Move());
VerifyData(data, nullptr, 0);
VerifyData(data2, nullptr, 0);
printf("\n -- PASS\n");
}