ported from mozilla: Add UnorderedRemoveElement[s]At to nsTArray, r=froydnj

This commit is contained in:
roytam1 2025-03-23 12:21:15 +08:00
commit 3fa9e61e7e
3 changed files with 260 additions and 1 deletions

View file

@ -202,4 +202,124 @@ TEST(TArray, CopyOverlappingBackwards)
}
}
TEST(TArray, UnorderedRemoveElements)
{
// When removing an element from the end of the array, it can be removed in
// place, by destroying it and decrementing the length.
//
// [ 1, 2, 3 ] => [ 1, 2 ]
// ^
{
nsTArray<int> array{ 1, 2, 3 };
array.UnorderedRemoveElementAt(2);
nsTArray<int> goal{ 1, 2 };
ASSERT_EQ(array, goal);
}
// When removing any other single element, it is removed by swapping it with
// the last element, and then decrementing the length as before.
//
// [ 1, 2, 3, 4, 5, 6 ] => [ 1, 6, 3, 4, 5 ]
// ^
{
nsTArray<int> array{1, 2, 3, 4, 5, 6};
array.UnorderedRemoveElementAt(1);
nsTArray<int> goal{1, 6, 3, 4, 5};
ASSERT_EQ(array, goal);
}
// This method also supports efficiently removing a range of elements. If they
// are at the end, then they can all be removed like in the one element case.
//
// [ 1, 2, 3, 4, 5, 6 ] => [ 1, 2 ]
// ^--------^
{
nsTArray<int> array{1, 2, 3, 4, 5, 6};
array.UnorderedRemoveElementsAt(2, 4);
nsTArray<int> goal{1, 2};
ASSERT_EQ(array, goal);
}
// If more elements are removed than exist after the removed section, the
// remaining elements will be shifted down like in a normal removal.
//
// [ 1, 2, 3, 4, 5, 6, 7, 8 ] => [ 1, 2, 7, 8 ]
// ^--------^
{
nsTArray<int> array{1, 2, 3, 4, 5, 6, 7, 8};
array.UnorderedRemoveElementsAt(2, 4);
nsTArray<int> goal{1, 2, 7, 8};
ASSERT_EQ(array, goal);
}
// And if fewer elements are removed than exist after the removed section,
// elements will be moved from the end of the array to fill the vacated space.
//
// [ 1, 2, 3, 4, 5, 6, 7, 8 ] => [ 1, 7, 8, 4, 5, 6 ]
// ^--^
{
nsTArray<int> array{1, 2, 3, 4, 5, 6, 7, 8};
array.UnorderedRemoveElementsAt(1, 2);
nsTArray<int> goal{1, 7, 8, 4, 5, 6};
ASSERT_EQ(array, goal);
}
// We should do the right thing if we drain the entire array.
{
nsTArray<int> array{1, 2, 3, 4, 5};
array.UnorderedRemoveElementsAt(0, 5);
nsTArray<int> goal{};
ASSERT_EQ(array, goal);
}
{
nsTArray<int> array{1};
array.UnorderedRemoveElementAt(0);
nsTArray<int> goal{};
ASSERT_EQ(array, goal);
}
// We should do the right thing if we remove the same number of elements that
// we have remaining.
{
nsTArray<int> array{1, 2, 3, 4, 5, 6};
array.UnorderedRemoveElementsAt(2, 2);
nsTArray<int> goal{1, 2, 5, 6};
ASSERT_EQ(array, goal);
}
{
nsTArray<int> array{1, 2, 3};
array.UnorderedRemoveElementAt(1);
nsTArray<int> goal{1, 3};
ASSERT_EQ(array, goal);
}
// We should be able to remove elements from the front without issue.
{
nsTArray<int> array{1, 2, 3, 4, 5, 6};
array.UnorderedRemoveElementsAt(0, 2);
nsTArray<int> goal{5, 6, 3, 4};
ASSERT_EQ(array, goal);
}
{
nsTArray<int> array{1, 2, 3, 4};
array.UnorderedRemoveElementAt(0);
nsTArray<int> goal{4, 2, 3};
ASSERT_EQ(array, goal);
}
}
} // namespace TestTArray