[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
+26 -2
View File
@@ -326,7 +326,7 @@ void TestHeapArrayOfUint16(void)
VerifyArray(array2, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26);
array2.TakeFrom(static_cast<Heap::Array<uint16_t, 2> &&>(array));
array2.TakeFrom(array.Move());
VerifyArray(array);
VerifyOrQuit(array.GetCapacity() == 0);
@@ -334,6 +334,18 @@ void TestHeapArrayOfUint16(void)
VerifyArray(array2, 0, 1, 2, 3, 4, 5);
VerifyOrQuit(array2.GetCapacity() == 10);
// Test moving from self
array2.TakeFrom(array2.Move());
VerifyArray(array2, 0, 1, 2, 3, 4, 5);
VerifyOrQuit(array2.GetCapacity() == 10);
// Test moving a null array
array2.TakeFrom(array.Move());
VerifyArray(array);
VerifyOrQuit(array.GetCapacity() == 0);
VerifyArray(array2);
VerifyOrQuit(array2.GetCapacity() == 0);
printf("\n -- PASS\n");
}
@@ -465,13 +477,25 @@ void TestHeapArray(void)
SuccessOrQuit(array2.PushBack(Entry(num + 0x20)));
}
array2.TakeFrom(static_cast<Heap::Array<Entry, 2> &&>(array));
array2.TakeFrom(array.Move());
VerifyOrQuit(array.GetLength() == 0);
VerifyOrQuit(array.GetCapacity() == 0);
VerifyArray(array2, 0, 1, 2, 3, 4, 5);
VerifyOrQuit(array2.GetCapacity() == 10);
// Test moving from self
array2.TakeFrom(array2.Move());
VerifyArray(array2, 0, 1, 2, 3, 4, 5);
VerifyOrQuit(array2.GetCapacity() == 10);
// Test moving a null array
array2.TakeFrom(array.Move());
VerifyArray(array);
VerifyOrQuit(array.GetCapacity() == 0);
VerifyArray(array2);
VerifyOrQuit(array2.GetCapacity() == 0);
}
printf("------------------------------------------------------------------------------------\n");