Add Array/BitArray tests and fix some detected problems
This commit is contained in:
@@ -112,15 +112,15 @@ public:
|
|||||||
/// Initializes a new instance of the <see cref="Array"/> class.
|
/// Initializes a new instance of the <see cref="Array"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="other">The other collection to copy.</param>
|
/// <param name="other">The other collection to copy.</param>
|
||||||
template<typename U>
|
template<typename OtherT = T, typename OtherAllocationType = AllocationType>
|
||||||
explicit Array(const Array<U>& other) noexcept
|
explicit Array(const Array<OtherT, OtherAllocationType>& other) noexcept
|
||||||
{
|
{
|
||||||
_capacity = other._count;
|
_capacity = other.Capacity();
|
||||||
_count = other._count;
|
_count = other.Count();
|
||||||
if (_capacity > 0)
|
if (_capacity > 0)
|
||||||
{
|
{
|
||||||
_allocation.Allocate(_capacity);
|
_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)
|
if (this != &other)
|
||||||
{
|
{
|
||||||
Memory::DestructItems(_allocation.Get(), _count);
|
Memory::DestructItems(_allocation.Get(), _count);
|
||||||
if (_capacity < other._count)
|
if (_capacity < other.Count())
|
||||||
{
|
{
|
||||||
_allocation.Free();
|
_allocation.Free();
|
||||||
_capacity = other._count;
|
_capacity = other.Count();
|
||||||
_allocation.Allocate(_capacity);
|
_allocation.Allocate(_capacity);
|
||||||
}
|
}
|
||||||
_count = other._count;
|
_count = other.Count();
|
||||||
Memory::ConstructItems(_allocation.Get(), other.Get(), _count);
|
Memory::ConstructItems(_allocation.Get(), other.Get(), _count);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
@@ -489,7 +489,7 @@ public:
|
|||||||
/// Adds the other collection to the collection.
|
/// Adds the other collection to the collection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="other">The other collection to add.</param>
|
/// <param name="other">The other collection to add.</param>
|
||||||
template<typename OtherT, typename OtherAllocationType = HeapAllocation>
|
template<typename OtherT, typename OtherAllocationType = AllocationType>
|
||||||
FORCE_INLINE void Add(const Array<OtherT, OtherAllocationType>& other)
|
FORCE_INLINE void Add(const Array<OtherT, OtherAllocationType>& other)
|
||||||
{
|
{
|
||||||
Add(other.Get(), other.Count());
|
Add(other.Get(), other.Count());
|
||||||
@@ -860,9 +860,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool operator==(const Array& other) const
|
template<typename OtherT = T, typename OtherAllocationType = AllocationType>
|
||||||
|
bool operator==(const Array<OtherT, OtherAllocationType>& other) const
|
||||||
{
|
{
|
||||||
if (_count == other._count)
|
if (_count == other.Count())
|
||||||
{
|
{
|
||||||
const T* data = _allocation.Get();
|
const T* data = _allocation.Get();
|
||||||
const T* otherData = other.Get();
|
const T* otherData = other.Get();
|
||||||
@@ -875,7 +876,8 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const Array& other) const
|
template<typename OtherT = T, typename OtherAllocationType = AllocationType>
|
||||||
|
bool operator!=(const Array<OtherT, OtherAllocationType>& other) const
|
||||||
{
|
{
|
||||||
return !operator==(other);
|
return !operator==(other);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ template<typename AllocationType = HeapAllocation>
|
|||||||
API_CLASS(InBuild) class BitArray
|
API_CLASS(InBuild) class BitArray
|
||||||
{
|
{
|
||||||
friend BitArray;
|
friend BitArray;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef uint64 ItemType;
|
typedef uint64 ItemType;
|
||||||
typedef typename AllocationType::template Data<ItemType> AllocationData;
|
typedef typename AllocationType::template Data<ItemType> AllocationData;
|
||||||
@@ -49,11 +48,31 @@ public:
|
|||||||
/// Initializes a new instance of the <see cref="BitArray"/> class.
|
/// Initializes a new instance of the <see cref="BitArray"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="other">The other collection to copy.</param>
|
/// <param name="other">The other collection to copy.</param>
|
||||||
BitArray(const BitArray& other)
|
BitArray(const BitArray& other) noexcept
|
||||||
{
|
{
|
||||||
_count = _capacity = other._count;
|
_count = _capacity = other.Count();
|
||||||
if (_capacity > 0)
|
if (_capacity > 0)
|
||||||
_allocation.Allocate(Math::Max<ItemType>(_capacity / sizeof(ItemType), 1));
|
{
|
||||||
|
const uint64 itemsCapacity = Math::Max<ItemType>(_capacity / sizeof(ItemType), 1);
|
||||||
|
_allocation.Allocate(itemsCapacity);
|
||||||
|
Platform::MemoryCopy(Get(), other.Get(), itemsCapacity * sizeof(ItemType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="BitArray"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="other">The other collection to copy.</param>
|
||||||
|
template<typename OtherAllocationType = AllocationType>
|
||||||
|
explicit BitArray(const BitArray<OtherAllocationType>& other) noexcept
|
||||||
|
{
|
||||||
|
_count = _capacity = other.Count();
|
||||||
|
if (_capacity > 0)
|
||||||
|
{
|
||||||
|
const uint64 itemsCapacity = Math::Max<ItemType>(_capacity / sizeof(ItemType), 1);
|
||||||
|
_allocation.Allocate(itemsCapacity);
|
||||||
|
Platform::MemoryCopy(Get(), other.Get(), itemsCapacity * sizeof(ItemType));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -82,7 +101,9 @@ public:
|
|||||||
{
|
{
|
||||||
_allocation.Free();
|
_allocation.Free();
|
||||||
_capacity = other._count;
|
_capacity = other._count;
|
||||||
_allocation.Allocate(Math::Max<ItemType>(_capacity / sizeof(ItemType), 1));
|
const uint64 itemsCapacity = Math::Max<ItemType>(_capacity / sizeof(ItemType), 1);
|
||||||
|
_allocation.Allocate(itemsCapacity);
|
||||||
|
Platform::MemoryCopy(Get(), other.Get(), itemsCapacity * sizeof(ItemType));
|
||||||
}
|
}
|
||||||
_count = other._count;
|
_count = other._count;
|
||||||
}
|
}
|
||||||
@@ -119,7 +140,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the pointer to the bits storage data (linear allocation).
|
/// Gets the pointer to the bits storage data (linear allocation).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The data pointer.</returns>
|
|
||||||
FORCE_INLINE ItemType* Get()
|
FORCE_INLINE ItemType* Get()
|
||||||
{
|
{
|
||||||
return _allocation.Get();
|
return _allocation.Get();
|
||||||
@@ -128,7 +148,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the pointer to the bits storage data (linear allocation).
|
/// Gets the pointer to the bits storage data (linear allocation).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The data pointer.</returns>
|
|
||||||
FORCE_INLINE const ItemType* Get() const
|
FORCE_INLINE const ItemType* Get() const
|
||||||
{
|
{
|
||||||
return _allocation.Get();
|
return _allocation.Get();
|
||||||
@@ -137,7 +156,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the amount of the items in the collection.
|
/// Gets the amount of the items in the collection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The amount of items.</returns>
|
|
||||||
FORCE_INLINE int32 Count() const
|
FORCE_INLINE int32 Count() const
|
||||||
{
|
{
|
||||||
return _count;
|
return _count;
|
||||||
@@ -146,7 +164,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the amount of the items that can be contained by collection without resizing.
|
/// Gets the amount of the items that can be contained by collection without resizing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The collection capacity.</returns>
|
|
||||||
FORCE_INLINE int32 Capacity() const
|
FORCE_INLINE int32 Capacity() const
|
||||||
{
|
{
|
||||||
return _capacity;
|
return _capacity;
|
||||||
@@ -155,7 +172,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if collection isn't empty.
|
/// Returns true if collection isn't empty.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if collection isn't empty, otherwise false.</returns>
|
|
||||||
FORCE_INLINE bool HasItems() const
|
FORCE_INLINE bool HasItems() const
|
||||||
{
|
{
|
||||||
return _count != 0;
|
return _count != 0;
|
||||||
@@ -164,7 +180,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if collection is empty.
|
/// Returns true if collection is empty.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if collection is empty, otherwise false.</returns>
|
|
||||||
FORCE_INLINE bool IsEmpty() const
|
FORCE_INLINE bool IsEmpty() const
|
||||||
{
|
{
|
||||||
return _count == 0;
|
return _count == 0;
|
||||||
@@ -316,4 +331,25 @@ public:
|
|||||||
::Swap(_capacity, other._capacity);
|
::Swap(_capacity, other._capacity);
|
||||||
_allocation.Swap(other._allocation);
|
_allocation.Swap(other._allocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
template<typename OtherAllocationType = AllocationType>
|
||||||
|
bool operator==(const BitArray<OtherAllocationType>& other) const
|
||||||
|
{
|
||||||
|
if (_count == other.Count())
|
||||||
|
{
|
||||||
|
for (int32 i = 0; i < _count; i++)
|
||||||
|
{
|
||||||
|
if (!(Get(i) == other.Get(i)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename OtherAllocationType = AllocationType>
|
||||||
|
bool operator!=(const BitArray<OtherAllocationType>& other) const
|
||||||
|
{
|
||||||
|
return !operator==(other);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
class FLAXENGINE_API RandomStream
|
class FLAXENGINE_API RandomStream
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Holds the initial seed.
|
/// Holds the initial seed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -25,7 +24,6 @@ private:
|
|||||||
mutable int32 _seed;
|
mutable int32 _seed;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Init
|
/// Init
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -46,22 +44,18 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets initial seed value
|
/// Gets initial seed value
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Initial seed.</returns>
|
|
||||||
int32 GetInitialSeed() const
|
int32 GetInitialSeed() const
|
||||||
{
|
{
|
||||||
return _initialSeed;
|
return _initialSeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current seed.
|
/// Gets the current seed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Current seed value.</returns>
|
|
||||||
int32 GetCurrentSeed() const
|
int32 GetCurrentSeed() const
|
||||||
{
|
{
|
||||||
return _seed;
|
return _seed;
|
||||||
@@ -94,11 +88,18 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a random number between 0 and MAXUINT.
|
/// Returns a random boolean.
|
||||||
|
/// </summary>
|
||||||
|
bool GetBool() const
|
||||||
|
{
|
||||||
|
MutateSeed();
|
||||||
|
return *(uint32*)&_seed < (MAX_uint32 / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a random number between 0 and MAX_uint32.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Random number.</returns>
|
|
||||||
uint32 GetUnsignedInt() const
|
uint32 GetUnsignedInt() const
|
||||||
{
|
{
|
||||||
MutateSeed();
|
MutateSeed();
|
||||||
@@ -108,7 +109,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a random number between 0 and 1.
|
/// Returns a random number between 0 and 1.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Random number.</returns>
|
|
||||||
float GetFraction() const
|
float GetFraction() const
|
||||||
{
|
{
|
||||||
MutateSeed();
|
MutateSeed();
|
||||||
@@ -121,7 +121,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a random number between 0 and 1.
|
/// Returns a random number between 0 and 1.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Random number.</returns>
|
|
||||||
FORCE_INLINE float Rand() const
|
FORCE_INLINE float Rand() const
|
||||||
{
|
{
|
||||||
return GetFraction();
|
return GetFraction();
|
||||||
@@ -130,7 +129,6 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a random vector of unit size.
|
/// Returns a random vector of unit size.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Random unit length vector</returns>
|
|
||||||
Float3 GetUnitVector() const
|
Float3 GetUnitVector() const
|
||||||
{
|
{
|
||||||
Float3 result;
|
Float3 result;
|
||||||
@@ -144,11 +142,10 @@ public:
|
|||||||
} while (l > 1.0f || l < ZeroTolerance);
|
} while (l > 1.0f || l < ZeroTolerance);
|
||||||
return Float3::Normalize(result);
|
return Float3::Normalize(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a random <see cref="Vector3"/> with components in a range between [0;1].
|
/// Gets a random <see cref="Vector3"/> with components in a range between [0;1].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A random <see cref="Vector3"/>.</returns>
|
|
||||||
Vector3 GetVector3() const
|
Vector3 GetVector3() const
|
||||||
{
|
{
|
||||||
return Vector3(GetFraction(), GetFraction(), GetFraction());
|
return Vector3(GetFraction(), GetFraction(), GetFraction());
|
||||||
@@ -157,11 +154,11 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper function for rand implementations.
|
/// Helper function for rand implementations.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="A">Top border</param>
|
/// <param name="a">Top border</param>
|
||||||
/// <returns>A random number in [0..A)</returns>
|
/// <returns>A random number in [0..A)</returns>
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -188,7 +185,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Mutates the current seed into the next seed.
|
/// Mutates the current seed into the next seed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
110
Source/Engine/Tests/TestCollections.cpp
Normal file
110
Source/Engine/Tests/TestCollections.cpp
Normal file
@@ -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 <ThirdParty/catch2/catch.hpp>
|
||||||
|
|
||||||
|
TEST_CASE("Array")
|
||||||
|
{
|
||||||
|
SECTION("Test Allocators")
|
||||||
|
{
|
||||||
|
Array<int32> a1;
|
||||||
|
Array<int32, InlinedAllocation<8>> a2;
|
||||||
|
Array<int32, FixedAllocation<8>> 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<uint32> 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<uint32> a1(testData);
|
||||||
|
const Array<uint32, InlinedAllocation<8>> a2(testData);
|
||||||
|
const Array<uint32, InlinedAllocation<64>> a3(testData);
|
||||||
|
const Array<uint32, FixedAllocation<64>> a4(testData);
|
||||||
|
CHECK(a1 == testData);
|
||||||
|
CHECK(a2 == testData);
|
||||||
|
CHECK(a3 == testData);
|
||||||
|
CHECK(a4 == testData);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Test Copy Operator")
|
||||||
|
{
|
||||||
|
Array<uint32> a1;
|
||||||
|
a1 = testData;
|
||||||
|
CHECK(a1 == testData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("BitArray")
|
||||||
|
{
|
||||||
|
SECTION("Test Allocators")
|
||||||
|
{
|
||||||
|
BitArray<> a1;
|
||||||
|
BitArray<InlinedAllocation<8>> a2;
|
||||||
|
BitArray<FixedAllocation<8>> 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<InlinedAllocation<8>> a2(testData);
|
||||||
|
const BitArray<InlinedAllocation<64>> a3(testData);
|
||||||
|
const BitArray<FixedAllocation<64>> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user