diff --git a/Source/Engine/Core/Collections/BitArray.h b/Source/Engine/Core/Collections/BitArray.h
index 1b601c72f..0a748f4bd 100644
--- a/Source/Engine/Core/Collections/BitArray.h
+++ b/Source/Engine/Core/Collections/BitArray.h
@@ -90,12 +90,10 @@ public:
///
/// The other collection to move.
FORCE_INLINE BitArray(BitArray&& other) noexcept
+ : _count(0)
+ , _capacity(0)
{
- _count = other._count;
- _capacity = other._capacity;
- other._count = 0;
- other._capacity = 0;
- _allocation.Swap(other._allocation);
+ Swap(other);
}
///
@@ -130,11 +128,9 @@ public:
if (this != &other)
{
_allocation.Free();
- _count = other._count;
- _capacity = other._capacity;
- other._count = 0;
- other._capacity = 0;
- _allocation.Swap(other._allocation);
+ _count = 0;
+ _capacity = 0;
+ Swap(other);
}
return *this;
}
@@ -337,9 +333,38 @@ public:
/// The other collection.
void Swap(BitArray& other)
{
+ if IF_CONSTEXPR (AllocationType::HasSwap)
+ _allocation.Swap(other._allocation);
+ else
+ {
+ // Move to temp
+ const int32 oldItemsCapacity = ToItemCount(_capacity);
+ const int32 otherItemsCapacity = ToItemCount(other._capacity);
+ AllocationData oldAllocation;
+ if (oldItemsCapacity)
+ {
+ oldAllocation.Allocate(oldItemsCapacity);
+ Memory::MoveItems(oldAllocation.Get(), _allocation.Get(), oldItemsCapacity);
+ _allocation.Free();
+ }
+
+ // Move other to source
+ if (otherItemsCapacity)
+ {
+ _allocation.Allocate(otherItemsCapacity);
+ Memory::MoveItems(_allocation.Get(), other._allocation.Get(), otherItemsCapacity);
+ other._allocation.Free();
+ }
+
+ // Move temp to other
+ if (oldItemsCapacity)
+ {
+ other._allocation.Allocate(oldItemsCapacity);
+ Memory::MoveItems(other._allocation.Get(), oldAllocation.Get(), oldItemsCapacity);
+ }
+ }
::Swap(_count, other._count);
::Swap(_capacity, other._capacity);
- _allocation.Swap(other._allocation);
}
public:
diff --git a/Source/Engine/Tests/TestCollections.cpp b/Source/Engine/Tests/TestCollections.cpp
index c54e98c15..f9b0e47ca 100644
--- a/Source/Engine/Tests/TestCollections.cpp
+++ b/Source/Engine/Tests/TestCollections.cpp
@@ -7,6 +7,24 @@
#include "Engine/Core/Collections/Dictionary.h"
#include
+const bool TestBits[] = { true, false, true, false };
+
+template
+void InitBitArray(BitArray& array)
+{
+ array.Add(TestBits, ARRAY_COUNT(TestBits));
+}
+
+template
+void CheckBitArray(const BitArray& array)
+{
+ CHECK(array.Count() == ARRAY_COUNT(TestBits));
+ for (int32 i = 0; i < ARRAY_COUNT(TestBits); i++)
+ {
+ CHECK(array[i] == TestBits[i]);
+ }
+}
+
TEST_CASE("Array")
{
SECTION("Test Allocators")
@@ -84,6 +102,44 @@ TEST_CASE("BitArray")
}
}
+ SECTION("Test Move/Copy")
+ {
+ BitArray<> array1;
+ BitArray> array2;
+ BitArray> array3;
+ BitArray> array4;
+
+ InitBitArray(array1);
+ InitBitArray(array2);
+ InitBitArray(array3);
+ InitBitArray(array4);
+
+ CheckBitArray(array1);
+ CheckBitArray(array2);
+ CheckBitArray(array3);
+ CheckBitArray(array4);
+
+ BitArray<> arrayClone1 = array1;
+ BitArray> arrayClone2(array1);
+ BitArray> arrayClone3(MoveTemp(array1));
+ BitArray<> arrayClone4(MoveTemp(array1));
+ BitArray> arrayClone5 = MoveTemp(array2);
+ BitArray> arrayClone6 = MoveTemp(array3);
+ BitArray> arrayClone7 = MoveTemp(array4);
+
+ CheckBitArray(arrayClone1);
+ CheckBitArray(arrayClone2);
+ CheckBitArray(arrayClone4);
+ CheckBitArray(arrayClone5);
+ CheckBitArray(arrayClone6);
+ CheckBitArray(arrayClone7);
+
+ CHECK(array1.Count() == 0);
+ CHECK(array2.Count() == 0);
+ CHECK(array3.Count() == 0);
+ CHECK(array4.Count() == 0);
+ }
+
// Generate some random data for testing
BitArray<> testData;
testData.Resize(32);