diff --git a/Source/Engine/Core/Collections/Array.h b/Source/Engine/Core/Collections/Array.h
index 01fe21b38..d5d93495f 100644
--- a/Source/Engine/Core/Collections/Array.h
+++ b/Source/Engine/Core/Collections/Array.h
@@ -112,15 +112,15 @@ public:
/// Initializes a new instance of the class.
///
/// The other collection to copy.
- template
- explicit Array(const Array& other) noexcept
+ template
+ explicit Array(const Array& other) noexcept
{
- _capacity = other._count;
- _count = other._count;
+ _capacity = other.Capacity();
+ _count = other.Count();
if (_capacity > 0)
{
_allocation.Allocate(_capacity);
- Memory::ConstructItems(_allocation.Get(), other._data, other._count);
+ Memory::ConstructItems(_allocation.Get(), other.Get(), _count);
}
}
@@ -164,13 +164,13 @@ public:
if (this != &other)
{
Memory::DestructItems(_allocation.Get(), _count);
- if (_capacity < other._count)
+ if (_capacity < other.Count())
{
_allocation.Free();
- _capacity = other._count;
+ _capacity = other.Count();
_allocation.Allocate(_capacity);
}
- _count = other._count;
+ _count = other.Count();
Memory::ConstructItems(_allocation.Get(), other.Get(), _count);
}
return *this;
@@ -489,7 +489,7 @@ public:
/// Adds the other collection to the collection.
///
/// The other collection to add.
- template
+ template
FORCE_INLINE void Add(const Array& other)
{
Add(other.Get(), other.Count());
@@ -860,9 +860,10 @@ public:
}
public:
- bool operator==(const Array& other) const
+ template
+ bool operator==(const Array& other) const
{
- if (_count == other._count)
+ if (_count == other.Count())
{
const T* data = _allocation.Get();
const T* otherData = other.Get();
@@ -875,7 +876,8 @@ public:
return true;
}
- bool operator!=(const Array& other) const
+ template
+ bool operator!=(const Array& other) const
{
return !operator==(other);
}
diff --git a/Source/Engine/Core/Collections/BitArray.h b/Source/Engine/Core/Collections/BitArray.h
index 7d6d50773..660b1e0fe 100644
--- a/Source/Engine/Core/Collections/BitArray.h
+++ b/Source/Engine/Core/Collections/BitArray.h
@@ -13,7 +13,6 @@ template
API_CLASS(InBuild) class BitArray
{
friend BitArray;
-
public:
typedef uint64 ItemType;
typedef typename AllocationType::template Data AllocationData;
@@ -49,11 +48,31 @@ public:
/// Initializes a new instance of the class.
///
/// The other collection to copy.
- BitArray(const BitArray& other)
+ BitArray(const BitArray& other) noexcept
{
- _count = _capacity = other._count;
+ _count = _capacity = other.Count();
if (_capacity > 0)
- _allocation.Allocate(Math::Max(_capacity / sizeof(ItemType), 1));
+ {
+ const uint64 itemsCapacity = Math::Max(_capacity / sizeof(ItemType), 1);
+ _allocation.Allocate(itemsCapacity);
+ Platform::MemoryCopy(Get(), other.Get(), itemsCapacity * sizeof(ItemType));
+ }
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The other collection to copy.
+ template
+ explicit BitArray(const BitArray& other) noexcept
+ {
+ _count = _capacity = other.Count();
+ if (_capacity > 0)
+ {
+ const uint64 itemsCapacity = Math::Max(_capacity / sizeof(ItemType), 1);
+ _allocation.Allocate(itemsCapacity);
+ Platform::MemoryCopy(Get(), other.Get(), itemsCapacity * sizeof(ItemType));
+ }
}
///
@@ -82,7 +101,9 @@ public:
{
_allocation.Free();
_capacity = other._count;
- _allocation.Allocate(Math::Max(_capacity / sizeof(ItemType), 1));
+ const uint64 itemsCapacity = Math::Max(_capacity / sizeof(ItemType), 1);
+ _allocation.Allocate(itemsCapacity);
+ Platform::MemoryCopy(Get(), other.Get(), itemsCapacity * sizeof(ItemType));
}
_count = other._count;
}
@@ -119,7 +140,6 @@ public:
///
/// Gets the pointer to the bits storage data (linear allocation).
///
- /// The data pointer.
FORCE_INLINE ItemType* Get()
{
return _allocation.Get();
@@ -128,7 +148,6 @@ public:
///
/// Gets the pointer to the bits storage data (linear allocation).
///
- /// The data pointer.
FORCE_INLINE const ItemType* Get() const
{
return _allocation.Get();
@@ -137,7 +156,6 @@ public:
///
/// Gets the amount of the items in the collection.
///
- /// The amount of items.
FORCE_INLINE int32 Count() const
{
return _count;
@@ -146,7 +164,6 @@ public:
///
/// Gets the amount of the items that can be contained by collection without resizing.
///
- /// The collection capacity.
FORCE_INLINE int32 Capacity() const
{
return _capacity;
@@ -155,7 +172,6 @@ public:
///
/// Returns true if collection isn't empty.
///
- /// True if collection isn't empty, otherwise false.
FORCE_INLINE bool HasItems() const
{
return _count != 0;
@@ -164,7 +180,6 @@ public:
///
/// Returns true if collection is empty.
///
- /// True if collection is empty, otherwise false.
FORCE_INLINE bool IsEmpty() const
{
return _count == 0;
@@ -316,4 +331,25 @@ public:
::Swap(_capacity, other._capacity);
_allocation.Swap(other._allocation);
}
+
+public:
+ template
+ bool operator==(const BitArray& other) const
+ {
+ if (_count == other.Count())
+ {
+ for (int32 i = 0; i < _count; i++)
+ {
+ if (!(Get(i) == other.Get(i)))
+ return false;
+ }
+ }
+ return true;
+ }
+
+ template
+ bool operator!=(const BitArray& other) const
+ {
+ return !operator==(other);
+ }
};
diff --git a/Source/Engine/Core/RandomStream.h b/Source/Engine/Core/RandomStream.h
index 3b1d43c3b..0d8ad48e2 100644
--- a/Source/Engine/Core/RandomStream.h
+++ b/Source/Engine/Core/RandomStream.h
@@ -13,7 +13,6 @@
class FLAXENGINE_API RandomStream
{
private:
-
///
/// Holds the initial seed.
///
@@ -25,7 +24,6 @@ private:
mutable int32 _seed;
public:
-
///
/// Init
///
@@ -46,22 +44,18 @@ public:
}
public:
-
///
/// Gets initial seed value
///
- /// Initial seed.
int32 GetInitialSeed() const
{
return _initialSeed;
}
public:
-
///
/// Gets the current seed.
///
- /// Current seed value.
int32 GetCurrentSeed() const
{
return _seed;
@@ -94,11 +88,18 @@ public:
}
public:
-
///
- /// Returns a random number between 0 and MAXUINT.
+ /// Returns a random boolean.
+ ///
+ bool GetBool() const
+ {
+ MutateSeed();
+ return *(uint32*)&_seed < (MAX_uint32 / 2);
+ }
+
+ ///
+ /// Returns a random number between 0 and MAX_uint32.
///
- /// Random number.
uint32 GetUnsignedInt() const
{
MutateSeed();
@@ -108,7 +109,6 @@ public:
///
/// Returns a random number between 0 and 1.
///
- /// Random number.
float GetFraction() const
{
MutateSeed();
@@ -121,7 +121,6 @@ public:
///
/// Returns a random number between 0 and 1.
///
- /// Random number.
FORCE_INLINE float Rand() const
{
return GetFraction();
@@ -130,7 +129,6 @@ public:
///
/// Returns a random vector of unit size.
///
- /// Random unit length vector
Float3 GetUnitVector() const
{
Float3 result;
@@ -144,11 +142,10 @@ public:
} while (l > 1.0f || l < ZeroTolerance);
return Float3::Normalize(result);
}
-
+
///
/// Gets a random with components in a range between [0;1].
///
- /// A random .
Vector3 GetVector3() const
{
return Vector3(GetFraction(), GetFraction(), GetFraction());
@@ -157,11 +154,11 @@ public:
///
/// Helper function for rand implementations.
///
- /// Top border
+ /// Top border
/// A random number in [0..A)
- FORCE_INLINE int32 RandHelper(int32 A) const
+ FORCE_INLINE int32 RandHelper(int32 a) const
{
- return A > 0 ? Math::TruncToInt(GetFraction() * ((float)A - ZeroTolerance)) : 0;
+ return a > 0 ? Math::TruncToInt(GetFraction() * ((float)a - ZeroTolerance)) : 0;
}
///
@@ -188,7 +185,6 @@ public:
}
protected:
-
///
/// Mutates the current seed into the next seed.
///
diff --git a/Source/Engine/Tests/TestCollections.cpp b/Source/Engine/Tests/TestCollections.cpp
new file mode 100644
index 000000000..a82ae40ce
--- /dev/null
+++ b/Source/Engine/Tests/TestCollections.cpp
@@ -0,0 +1,110 @@
+// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
+
+#include "Engine/Core/RandomStream.h"
+#include "Engine/Core/Collections/Array.h"
+#include "Engine/Core/Collections/BitArray.h"
+#include
+
+TEST_CASE("Array")
+{
+ SECTION("Test Allocators")
+ {
+ Array a1;
+ Array> a2;
+ Array> a3;
+ for (int32 i = 0; i < 7; i++)
+ {
+ a1.Add(i);
+ a2.Add(i);
+ a3.Add(i);
+ }
+ CHECK(a1.Count() == 7);
+ CHECK(a2.Count() == 7);
+ CHECK(a3.Count() == 7);
+ for (int32 i = 0; i < 7; i++)
+ {
+ CHECK(a1[i] == i);
+ CHECK(a2[i] == i);
+ CHECK(a3[i] == i);
+ }
+ }
+
+ // Generate some random data for testing
+ Array testData;
+ testData.Resize(32);
+ RandomStream rand(101);
+ for (int32 i = 0; i < testData.Count(); i++)
+ testData[i] = rand.GetUnsignedInt();
+
+ SECTION("Test Copy Constructor")
+ {
+ const Array a1(testData);
+ const Array> a2(testData);
+ const Array> a3(testData);
+ const Array> a4(testData);
+ CHECK(a1 == testData);
+ CHECK(a2 == testData);
+ CHECK(a3 == testData);
+ CHECK(a4 == testData);
+ }
+
+ SECTION("Test Copy Operator")
+ {
+ Array a1;
+ a1 = testData;
+ CHECK(a1 == testData);
+ }
+}
+
+TEST_CASE("BitArray")
+{
+ SECTION("Test Allocators")
+ {
+ BitArray<> a1;
+ BitArray> a2;
+ BitArray> a3;
+ for (int32 i = 0; i < 7; i++)
+ {
+ const bool v = i & 2;
+ a1.Add(v);
+ a2.Add(v);
+ a3.Add(v);
+ }
+ CHECK(a1.Count() == 7);
+ CHECK(a2.Count() == 7);
+ CHECK(a3.Count() == 7);
+ for (int32 i = 0; i < 7; i++)
+ {
+ const bool v = i & 2;
+ CHECK(a1.Get(i) == v);
+ CHECK(a2.Get(i) == v);
+ CHECK(a3.Get(i) == v);
+ }
+ }
+
+ // Generate some random data for testing
+ BitArray<> testData;
+ testData.Resize(32);
+ RandomStream rand(101);
+ for (int32 i = 0; i < testData.Count(); i++)
+ testData.Set(i, rand.GetBool());
+
+ SECTION("Test Copy Constructor")
+ {
+ const BitArray<> a1(testData);
+ const BitArray> a2(testData);
+ const BitArray> a3(testData);
+ const BitArray> a4(testData);
+ CHECK(a1 == testData);
+ CHECK(a2 == testData);
+ CHECK(a3 == testData);
+ CHECK(a4 == testData);
+ }
+
+ SECTION("Test Copy Operator")
+ {
+ BitArray<> a1;
+ a1 = testData;
+ CHECK(a1 == testData);
+ }
+}