774 lines
23 KiB
C#
774 lines
23 KiB
C#
using NUnit.Framework;
|
|
using System;
|
|
using Unity.Burst;
|
|
using Unity.Collections;
|
|
using Unity.Collections.Tests;
|
|
using Unity.Collections.LowLevel.Unsafe;
|
|
using Unity.Jobs;
|
|
|
|
internal class UnsafeListTests : CollectionsTestCommonBase
|
|
{
|
|
[Test]
|
|
public void UnsafeListT_Init()
|
|
{
|
|
var container = new UnsafeList<int>(0, Allocator.Persistent, NativeArrayOptions.ClearMemory);
|
|
Assert.True(container.IsCreated);
|
|
Assert.True(container.IsEmpty);
|
|
Assert.DoesNotThrow(() => container.Dispose());
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void UnsafeListT_Init_ClearMemory()
|
|
{
|
|
var list = new UnsafeList<int>(10, Allocator.Persistent, NativeArrayOptions.ClearMemory);
|
|
|
|
for (var i = 0; i < list.Length; ++i)
|
|
{
|
|
Assert.AreEqual(0, UnsafeUtility.ReadArrayElement<int>(list.Ptr, i));
|
|
}
|
|
|
|
list.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void UnsafeListT_Allocate_Deallocate_Read_Write()
|
|
{
|
|
var list = new UnsafeList<int>(0, Allocator.Persistent);
|
|
Assert.True(list.IsCreated);
|
|
Assert.True(list.IsEmpty);
|
|
|
|
list.Add(1);
|
|
list.Add(2);
|
|
|
|
Assert.AreEqual(2, list.Length);
|
|
Assert.AreEqual(1, UnsafeUtility.ReadArrayElement<int>(list.Ptr, 0));
|
|
Assert.AreEqual(2, UnsafeUtility.ReadArrayElement<int>(list.Ptr, 1));
|
|
|
|
list.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void UnsafeListT_Resize_ClearMemory()
|
|
{
|
|
var list = new UnsafeList<int>(5, Allocator.Persistent, NativeArrayOptions.ClearMemory);
|
|
list.SetCapacity(32);
|
|
var capacity = list.Capacity;
|
|
|
|
list.Resize(5, NativeArrayOptions.UninitializedMemory);
|
|
Assert.AreEqual(capacity, list.Capacity); // list capacity should not change on resize
|
|
|
|
for (var i = 0; i < 5; ++i)
|
|
{
|
|
UnsafeUtility.WriteArrayElement(list.Ptr, i, i);
|
|
}
|
|
|
|
list.Resize(10, NativeArrayOptions.ClearMemory);
|
|
Assert.AreEqual(capacity, list.Capacity); // list capacity should not change on resize
|
|
|
|
for (var i = 0; i < 5; ++i)
|
|
{
|
|
Assert.AreEqual(i, UnsafeUtility.ReadArrayElement<int>(list.Ptr, i));
|
|
}
|
|
|
|
for (var i = 5; i < list.Length; ++i)
|
|
{
|
|
Assert.AreEqual(0, UnsafeUtility.ReadArrayElement<int>(list.Ptr, i));
|
|
}
|
|
|
|
list.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void UnsafeListT_Resize_Zero()
|
|
{
|
|
var list = new UnsafeList<int>(5, Allocator.Persistent, NativeArrayOptions.ClearMemory);
|
|
var capacity = list.Capacity;
|
|
|
|
list.Add(1);
|
|
list.Resize(0);
|
|
Assert.AreEqual(0, list.Length);
|
|
Assert.AreEqual(capacity, list.Capacity); // list capacity should not change on resize
|
|
|
|
list.Add(2);
|
|
list.Clear();
|
|
Assert.AreEqual(0, list.Length);
|
|
Assert.AreEqual(capacity, list.Capacity); // list capacity should not change on resize
|
|
|
|
list.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void UnsafeListT_SetCapacity()
|
|
{
|
|
using (var list = new UnsafeList<int>(1, Allocator.Persistent, NativeArrayOptions.ClearMemory))
|
|
{
|
|
list.Add(1);
|
|
Assert.DoesNotThrow(() => list.SetCapacity(128));
|
|
|
|
list.Add(1);
|
|
Assert.AreEqual(2, list.Length);
|
|
#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
|
|
Assert.Throws<ArgumentOutOfRangeException>(() => list.SetCapacity(1));
|
|
#endif
|
|
|
|
list.RemoveAtSwapBack(0);
|
|
Assert.AreEqual(1, list.Length);
|
|
Assert.DoesNotThrow(() => list.SetCapacity(1));
|
|
|
|
list.TrimExcess();
|
|
Assert.AreEqual(1, list.Capacity);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void UnsafeListT_TrimExcess()
|
|
{
|
|
using (var list = new UnsafeList<int>(32, Allocator.Persistent, NativeArrayOptions.ClearMemory))
|
|
{
|
|
list.Add(1);
|
|
list.TrimExcess();
|
|
Assert.AreEqual(1, list.Length);
|
|
Assert.AreEqual(1, list.Capacity);
|
|
|
|
list.RemoveAtSwapBack(0);
|
|
Assert.AreEqual(list.Length, 0);
|
|
list.TrimExcess();
|
|
Assert.AreEqual(list.Capacity, 0);
|
|
|
|
list.Add(1);
|
|
Assert.AreEqual(list.Length, 1);
|
|
Assert.AreNotEqual(list.Capacity, 0);
|
|
|
|
list.Clear();
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void UnsafeListT_DisposeJob()
|
|
{
|
|
var list = new UnsafeList<int>(5, Allocator.Persistent, NativeArrayOptions.ClearMemory);
|
|
|
|
var disposeJob = list.Dispose(default);
|
|
|
|
Assert.IsTrue(list.Ptr == null);
|
|
|
|
disposeJob.Complete();
|
|
}
|
|
|
|
unsafe void Expected(ref UnsafeList<int> list, int expectedLength, int[] expected)
|
|
{
|
|
Assert.AreEqual(0 == expectedLength, list.IsEmpty);
|
|
Assert.AreEqual(list.Length, expectedLength);
|
|
for (var i = 0; i < list.Length; ++i)
|
|
{
|
|
var value = UnsafeUtility.ReadArrayElement<int>(list.Ptr, i);
|
|
Assert.AreEqual(expected[i], value);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void UnsafeListT_AddReplicate()
|
|
{
|
|
using (var list = new UnsafeList<int>(32, Allocator.Persistent))
|
|
{
|
|
list.AddReplicate(value: 42, count: 10);
|
|
Assert.AreEqual(10, list.Length);
|
|
foreach (var item in list)
|
|
Assert.AreEqual(42, item);
|
|
|
|
list.AddReplicate(value: 42, count: 100);
|
|
Assert.AreEqual(110, list.Length);
|
|
foreach (var item in list)
|
|
Assert.AreEqual(42, item);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void UnsafeListT_AddNoResize()
|
|
{
|
|
var container = new UnsafeList<int>(1, Allocator.Persistent, NativeArrayOptions.ClearMemory);
|
|
|
|
// List's capacity is always cache-line aligned, number of items fills up whole cache-line.
|
|
int[] range = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
|
|
|
|
#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
|
|
Assert.Throws<InvalidOperationException>(() => { fixed (int* r = range) container.AddRangeNoResize(r, 17); });
|
|
#endif
|
|
|
|
container.SetCapacity(17);
|
|
Assert.DoesNotThrow(() => { fixed (int* r = range) container.AddRangeNoResize(r, 17); });
|
|
|
|
container.Length = 16;
|
|
container.TrimExcess();
|
|
|
|
#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
|
|
Assert.Throws<InvalidOperationException>(() => { container.AddNoResize(16); });
|
|
#endif
|
|
|
|
container.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void UnsafeListT_AddNoResize_Read()
|
|
{
|
|
var container = new UnsafeList<int>(4, Allocator.Persistent, NativeArrayOptions.ClearMemory);
|
|
container.AddNoResize(4);
|
|
container.AddNoResize(6);
|
|
container.AddNoResize(4);
|
|
container.AddNoResize(9);
|
|
Expected(ref container, 4, new int[] { 4, 6, 4, 9 });
|
|
|
|
container.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void UnsafeListT_RemoveAtSwapBack()
|
|
{
|
|
var list = new UnsafeList<int>(10, Allocator.Persistent, NativeArrayOptions.ClearMemory);
|
|
|
|
int[] range = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
|
|
|
// test removing from the end
|
|
fixed (int* r = range) list.AddRange(r, 10);
|
|
list.RemoveAtSwapBack(list.Length - 1);
|
|
Expected(ref list, 9, new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 });
|
|
list.Clear();
|
|
|
|
// test removing from the end
|
|
fixed (int* r = range) list.AddRange(r, 10);
|
|
list.RemoveAtSwapBack(5);
|
|
Expected(ref list, 9, new int[] { 0, 1, 2, 3, 4, 9, 6, 7, 8 });
|
|
list.Clear();
|
|
|
|
list.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void UnsafeListT_RemoveRangeSwapBackBE()
|
|
{
|
|
var list = new UnsafeList<int>(10, Allocator.Persistent, NativeArrayOptions.ClearMemory);
|
|
|
|
int[] range = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
|
|
|
// test removing from the end
|
|
fixed (int* r = range) list.AddRange(r, 10);
|
|
list.RemoveRangeSwapBack(6, 3);
|
|
Expected(ref list, 7, new int[] { 0, 1, 2, 3, 4, 5, 9 });
|
|
list.Clear();
|
|
|
|
// test removing all but one
|
|
fixed (int* r = range) list.AddRange(r, 10);
|
|
list.RemoveRangeSwapBack(0, 9);
|
|
Expected(ref list, 1, new int[] { 9 });
|
|
list.Clear();
|
|
|
|
// test removing from the front
|
|
fixed (int* r = range) list.AddRange(r, 10);
|
|
list.RemoveRangeSwapBack(0, 3);
|
|
Expected(ref list, 7, new int[] { 7, 8, 9, 3, 4, 5, 6 });
|
|
list.Clear();
|
|
|
|
// test removing from the middle
|
|
fixed (int* r = range) list.AddRange(r, 10);
|
|
list.RemoveRangeSwapBack(0, 3);
|
|
Expected(ref list, 7, new int[] { 7, 8, 9, 3, 4, 5, 6 });
|
|
list.Clear();
|
|
|
|
// test removing whole range
|
|
fixed (int* r = range) list.AddRange(r, 10);
|
|
list.RemoveRangeSwapBack(0, 10);
|
|
Expected(ref list, 0, new int[] { 0 });
|
|
list.Clear();
|
|
|
|
list.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void UnsafeListT_RemoveAt()
|
|
{
|
|
var list = new UnsafeList<int>(10, Allocator.Persistent, NativeArrayOptions.ClearMemory);
|
|
|
|
int[] range = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
|
|
|
// test removing from the end
|
|
fixed (int* r = range) list.AddRange(r, 10);
|
|
list.RemoveAt(list.Length - 1);
|
|
Expected(ref list, 9, new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 });
|
|
list.Clear();
|
|
|
|
// test removing from the end
|
|
fixed (int* r = range) list.AddRange(r, 10);
|
|
list.RemoveAt(5);
|
|
Expected(ref list, 9, new int[] { 0, 1, 2, 3, 4, 6, 7, 8, 9 });
|
|
list.Clear();
|
|
|
|
list.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void UnsafeListT_RemoveRange()
|
|
{
|
|
var list = new UnsafeList<int>(10, Allocator.Persistent, NativeArrayOptions.ClearMemory);
|
|
|
|
int[] range = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
|
|
|
// test removing from the end
|
|
fixed (int* r = range) list.AddRange(r, 10);
|
|
list.RemoveRange(6, 3);
|
|
Expected(ref list, 7, new int[] { 0, 1, 2, 3, 4, 5, 9 });
|
|
list.Clear();
|
|
|
|
// test removing all but one
|
|
fixed (int* r = range) list.AddRange(r, 10);
|
|
list.RemoveRange(0, 9);
|
|
Expected(ref list, 1, new int[] { 9 });
|
|
list.Clear();
|
|
|
|
// test removing from the front
|
|
fixed (int* r = range) list.AddRange(r, 10);
|
|
list.RemoveRange(0, 3);
|
|
Expected(ref list, 7, new int[] { 3, 4, 5, 6, 7, 8, 9 });
|
|
list.Clear();
|
|
|
|
// test removing from the middle
|
|
fixed (int* r = range) list.AddRange(r, 10);
|
|
list.RemoveRange(0, 3);
|
|
Expected(ref list, 7, new int[] { 3, 4, 5, 6, 7, 8, 9 });
|
|
list.Clear();
|
|
|
|
// test removing whole range
|
|
fixed (int* r = range) list.AddRange(r, 10);
|
|
list.RemoveRange(0, 10);
|
|
Expected(ref list, 0, new int[] { 0 });
|
|
list.Clear();
|
|
|
|
// Test removing at the end of the list with a zero length.
|
|
// This simply must not throw.
|
|
list.RemoveRange(list.Length, 0);
|
|
|
|
list.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
[TestRequiresDotsDebugOrCollectionChecks]
|
|
public unsafe void UnsafeListT_Remove_Throws()
|
|
{
|
|
var list = new UnsafeList<int>(10, Allocator.Persistent, NativeArrayOptions.ClearMemory);
|
|
|
|
Assert.Throws<IndexOutOfRangeException>(() => { list.RemoveAt(0); });
|
|
Assert.AreEqual(0, list.Length);
|
|
|
|
Assert.Throws<IndexOutOfRangeException>(() => { list.RemoveAtSwapBack(0); });
|
|
Assert.AreEqual(0, list.Length);
|
|
|
|
int[] range = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
|
fixed (int* r = range) list.AddRange(r, 10);
|
|
|
|
Assert.Throws<IndexOutOfRangeException>(() => { list.RemoveAt(100); });
|
|
Assert.AreEqual(10, list.Length);
|
|
|
|
Assert.Throws<IndexOutOfRangeException>(() => { list.RemoveAtSwapBack(100); });
|
|
Assert.AreEqual(10, list.Length);
|
|
|
|
Assert.Throws<ArgumentOutOfRangeException>(() => { list.RemoveRange(0, 100); });
|
|
Assert.AreEqual(10, list.Length);
|
|
|
|
Assert.Throws<ArgumentOutOfRangeException>(() => { list.RemoveRangeSwapBack(0, 100); });
|
|
Assert.AreEqual(10, list.Length);
|
|
|
|
Assert.Throws<ArgumentOutOfRangeException>(() => { list.RemoveRange(100, -1); });
|
|
Assert.AreEqual(10, list.Length);
|
|
|
|
Assert.Throws<ArgumentOutOfRangeException>(() => { list.RemoveRangeSwapBack(100, -1); });
|
|
Assert.AreEqual(10, list.Length);
|
|
|
|
list.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void UnsafeListT_PtrLength()
|
|
{
|
|
var list = new UnsafeList<int>(10, Allocator.Persistent, NativeArrayOptions.ClearMemory);
|
|
|
|
int[] range = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
|
fixed (int* r = range) list.AddRange(r, 10);
|
|
|
|
var listView = new UnsafeList<int>(list.Ptr + 4, 2);
|
|
Expected(ref listView, 2, new int[] { 4, 5 });
|
|
|
|
listView.Dispose();
|
|
list.Dispose();
|
|
}
|
|
|
|
// Burst error BC1071: Unsupported assert type
|
|
// [BurstCompile(CompileSynchronously = true)]
|
|
struct UnsafeListAsReadOnly : IJob
|
|
{
|
|
public UnsafeList<int>.ReadOnly list;
|
|
|
|
public void Execute()
|
|
{
|
|
Assert.True(list.Contains(123));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void UnsafeListT_AsReadOnly()
|
|
{
|
|
var list = new UnsafeList<int>(10, Allocator.Persistent, NativeArrayOptions.ClearMemory);
|
|
list.Add(123);
|
|
|
|
var job = new UnsafeListAsReadOnly
|
|
{
|
|
list = list.AsReadOnly(),
|
|
};
|
|
|
|
list.Dispose(job.Schedule()).Complete();
|
|
}
|
|
|
|
[BurstCompile(CompileSynchronously = true)]
|
|
struct UnsafeListParallelWriter : IJobParallelFor
|
|
{
|
|
public UnsafeList<int>.ParallelWriter list;
|
|
|
|
public void Execute(int index)
|
|
{
|
|
list.AddNoResize(index);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void UnsafeListT_ParallelWriter()
|
|
{
|
|
var list = new UnsafeList<int>(256, Allocator.Persistent, NativeArrayOptions.ClearMemory);
|
|
|
|
var job = new UnsafeListParallelWriter
|
|
{
|
|
list = list.AsParallelWriter(),
|
|
};
|
|
|
|
job.Schedule(list.Capacity, 1).Complete();
|
|
|
|
Assert.AreEqual(list.Length, list.Capacity);
|
|
|
|
list.Sort<int>();
|
|
|
|
for (int i = 0; i < list.Length; i++)
|
|
{
|
|
unsafe
|
|
{
|
|
var value = UnsafeUtility.ReadArrayElement<int>(list.Ptr, i);
|
|
Assert.AreEqual(i, value);
|
|
}
|
|
}
|
|
|
|
list.Dispose();
|
|
}
|
|
|
|
[BurstCompile(CompileSynchronously = true)]
|
|
struct UnsafeListTestParallelWriter : IJob
|
|
{
|
|
[WriteOnly]
|
|
public UnsafeList<int>.ParallelWriter writer;
|
|
|
|
public unsafe void Execute()
|
|
{
|
|
var range = stackalloc int[2] { 7, 3 };
|
|
|
|
writer.AddNoResize(range[0]);
|
|
writer.AddRangeNoResize(range, 1);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void UnsafeListT_ParallelWriter_NoPtrCaching()
|
|
{
|
|
UnsafeList<int> list;
|
|
|
|
{
|
|
list = new UnsafeList<int>(2, Allocator.Persistent);
|
|
var writer = list.AsParallelWriter();
|
|
list.SetCapacity(100);
|
|
var writerJob = new UnsafeListTestParallelWriter { writer = writer }.Schedule();
|
|
writerJob.Complete();
|
|
}
|
|
|
|
Assert.AreEqual(2, list.Length);
|
|
Assert.AreEqual(7, list[0]);
|
|
Assert.AreEqual(7, list[1]);
|
|
|
|
list.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void UnsafeListT_IndexOf()
|
|
{
|
|
using (var list = new UnsafeList<int>(10, Allocator.Persistent) { 123, 789 })
|
|
{
|
|
bool r0 = false, r1 = false, r2 = false;
|
|
|
|
GCAllocRecorder.ValidateNoGCAllocs(() =>
|
|
{
|
|
r0 = -1 != list.IndexOf(456);
|
|
r1 = list.Contains(123);
|
|
r2 = list.Contains(789);
|
|
});
|
|
|
|
Assert.False(r0);
|
|
Assert.True(r1);
|
|
Assert.True(r2);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void UnsafeListT_InsertRangeWithBeginEnd()
|
|
{
|
|
var list = new UnsafeList<byte>(3, Allocator.Persistent);
|
|
list.Add(0);
|
|
list.Add(3);
|
|
list.Add(4);
|
|
Assert.AreEqual(3, list.Length);
|
|
|
|
#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
|
|
Assert.Throws<ArgumentOutOfRangeException>(() => list.InsertRangeWithBeginEnd(-1, 8));
|
|
Assert.Throws<ArgumentException>(() => list.InsertRangeWithBeginEnd(3, 1));
|
|
#endif
|
|
|
|
Assert.DoesNotThrow(() => list.InsertRangeWithBeginEnd(1, 3));
|
|
Assert.AreEqual(5, list.Length);
|
|
|
|
list[1] = 1;
|
|
list[2] = 2;
|
|
|
|
for (var i = 0; i < list.Length; ++i)
|
|
{
|
|
Assert.AreEqual(i, list[i]);
|
|
}
|
|
|
|
Assert.DoesNotThrow(() => list.InsertRangeWithBeginEnd(5, 8));
|
|
Assert.AreEqual(8, list.Length);
|
|
|
|
list[5] = 5;
|
|
list[6] = 6;
|
|
list[7] = 7;
|
|
|
|
for (var i = 0; i < list.Length; ++i)
|
|
{
|
|
Assert.AreEqual(i, list[i]);
|
|
}
|
|
|
|
list.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
public void UnsafeListT_InsertRange()
|
|
{
|
|
var list = new UnsafeList<byte>(3, Allocator.Persistent);
|
|
list.Add(0);
|
|
list.Add(3);
|
|
list.Add(4);
|
|
Assert.AreEqual(3, list.Length);
|
|
|
|
#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
|
|
Assert.Throws<ArgumentOutOfRangeException>(() => list.InsertRange(-1, 8));
|
|
Assert.Throws<ArgumentException>(() => list.InsertRange(3, -1));
|
|
#endif
|
|
|
|
Assert.DoesNotThrow(() => list.InsertRange(1, 0));
|
|
Assert.AreEqual(3, list.Length);
|
|
|
|
Assert.DoesNotThrow(() => list.InsertRange(1, 2));
|
|
Assert.AreEqual(5, list.Length);
|
|
|
|
list[1] = 1;
|
|
list[2] = 2;
|
|
|
|
for (var i = 0; i < list.Length; ++i)
|
|
{
|
|
Assert.AreEqual(i, list[i]);
|
|
}
|
|
|
|
Assert.DoesNotThrow(() => list.InsertRange(5, 3));
|
|
Assert.AreEqual(8, list.Length);
|
|
|
|
list[5] = 5;
|
|
list[6] = 6;
|
|
list[7] = 7;
|
|
|
|
for (var i = 0; i < list.Length; ++i)
|
|
{
|
|
Assert.AreEqual(i, list[i]);
|
|
}
|
|
|
|
list.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
public void UnsafeListT_ForEach([Values(10, 1000)] int n)
|
|
{
|
|
var seen = new NativeArray<int>(n, Allocator.Temp);
|
|
using (var container = new UnsafeList<int>(32, CommonRwdAllocator.Handle))
|
|
{
|
|
for (int i = 0; i < n; i++)
|
|
{
|
|
container.Add(i);
|
|
}
|
|
|
|
var count = 0;
|
|
unsafe
|
|
{
|
|
UnsafeList<int>* test = &container;
|
|
|
|
foreach (var item in *test)
|
|
{
|
|
Assert.True(test->Contains(item));
|
|
seen[item] = seen[item] + 1;
|
|
++count;
|
|
}
|
|
}
|
|
|
|
Assert.AreEqual(container.Length, count);
|
|
for (int i = 0; i < n; i++)
|
|
{
|
|
Assert.AreEqual(1, seen[i], $"Incorrect item count {i}");
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void UnsafeListT_CustomAllocatorTest()
|
|
{
|
|
AllocatorManager.Initialize();
|
|
var allocatorHelper = new AllocatorHelper<CustomAllocatorTests.CountingAllocator>(AllocatorManager.Persistent);
|
|
ref var allocator = ref allocatorHelper.Allocator;
|
|
allocator.Initialize();
|
|
|
|
using (var container = new UnsafeList<byte>(1, allocator.Handle))
|
|
{
|
|
}
|
|
|
|
Assert.IsTrue(allocator.WasUsed);
|
|
allocator.Dispose();
|
|
allocatorHelper.Dispose();
|
|
AllocatorManager.Shutdown();
|
|
}
|
|
|
|
[BurstCompile]
|
|
struct BurstedCustomAllocatorJob : IJob
|
|
{
|
|
[NativeDisableUnsafePtrRestriction]
|
|
public unsafe CustomAllocatorTests.CountingAllocator* Allocator;
|
|
|
|
public void Execute()
|
|
{
|
|
unsafe
|
|
{
|
|
using (var container = new UnsafeList<byte>(1, Allocator->Handle))
|
|
{
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void UnsafeListT_BurstedCustomAllocatorTest()
|
|
{
|
|
AllocatorManager.Initialize();
|
|
var allocatorHelper = new AllocatorHelper<CustomAllocatorTests.CountingAllocator>(AllocatorManager.Persistent);
|
|
ref var allocator = ref allocatorHelper.Allocator;
|
|
allocator.Initialize();
|
|
|
|
var allocatorPtr = (CustomAllocatorTests.CountingAllocator*)UnsafeUtility.AddressOf(ref allocator);
|
|
unsafe
|
|
{
|
|
var handle = new BurstedCustomAllocatorJob { Allocator = allocatorPtr }.Schedule();
|
|
handle.Complete();
|
|
}
|
|
|
|
Assert.IsTrue(allocator.WasUsed);
|
|
allocator.Dispose();
|
|
allocatorHelper.Dispose();
|
|
AllocatorManager.Shutdown();
|
|
}
|
|
|
|
void IIndexableTest<T>(T container)
|
|
where T : unmanaged, IIndexable<int>
|
|
{
|
|
var length = container.Length;
|
|
|
|
Assert.Throws<IndexOutOfRangeException>(() => container.ElementAt(-1));
|
|
Assert.Throws<IndexOutOfRangeException>(() => container.ElementAt(container.Length));
|
|
|
|
Assert.DoesNotThrow(() => { for (int i = 0, len = container.Length; i < len; ++i) { container.ElementAt(i) = 4; } });
|
|
|
|
for (int i = 0, len = container.Length; i < len; ++i)
|
|
{
|
|
Assert.AreEqual(4, container.ElementAt(i));
|
|
}
|
|
}
|
|
|
|
void INativeListTest<T>(T container)
|
|
where T : unmanaged, INativeList<int>
|
|
{
|
|
var length = container.Length;
|
|
|
|
Assert.Throws<IndexOutOfRangeException>(() => container[-1] = 1);
|
|
Assert.Throws<IndexOutOfRangeException>(() => container[container.Length] = 1);
|
|
|
|
Assert.DoesNotThrow(() => { for (int i = 0, len = container.Length; i < len; ++i) { container[i] = 4; } });
|
|
|
|
Assert.Throws<ArgumentOutOfRangeException>(() => container.Capacity = container.Length - 1);
|
|
Assert.DoesNotThrow(() => container.Capacity = container.Length);
|
|
Assert.DoesNotThrow(() => container.Capacity = container.Length + 1);
|
|
|
|
for (int i = 0, len = container.Length; i < len; ++i)
|
|
{
|
|
Assert.AreEqual(4, container[i]);
|
|
}
|
|
}
|
|
|
|
private unsafe void TestInterfaces<T>(T container)
|
|
where T : unmanaged, IIndexable<int>, INativeList<int>
|
|
{
|
|
container.Length = 4;
|
|
Assert.DoesNotThrow(() => { for (int i = 0, len = container.Length; i < len; ++i) { container.ElementAt(i) = i; } });
|
|
|
|
IIndexableTest(container);
|
|
INativeListTest(container);
|
|
}
|
|
private unsafe void TestInterfacesDispose<T>(T container)
|
|
where T : unmanaged, IIndexable<int>, INativeList<int>, IDisposable
|
|
{
|
|
TestInterfaces(container);
|
|
container.Dispose();
|
|
}
|
|
|
|
[Test]
|
|
[TestRequiresDotsDebugOrCollectionChecks]
|
|
public unsafe void UnsafeListT_TestInterfaces() => TestInterfacesDispose(new UnsafeList<int>(1, CommonRwdAllocator.Handle));
|
|
|
|
[Test]
|
|
[TestRequiresDotsDebugOrCollectionChecks]
|
|
public unsafe void NativeList_TestInterfaces() => TestInterfacesDispose(new NativeList<int>(1, CommonRwdAllocator.Handle));
|
|
|
|
[Test]
|
|
[TestRequiresDotsDebugOrCollectionChecks]
|
|
public unsafe void FixedList32Bytes_TestInterfaces() => TestInterfaces(new FixedList32Bytes<int>());
|
|
|
|
[Test]
|
|
[TestRequiresDotsDebugOrCollectionChecks]
|
|
public unsafe void FixedList64Bytes_TestInterfaces() => TestInterfaces(new FixedList64Bytes<int>());
|
|
|
|
[Test]
|
|
[TestRequiresDotsDebugOrCollectionChecks]
|
|
public unsafe void FixedList128Bytes_TestInterfaces() => TestInterfaces(new FixedList128Bytes<int>());
|
|
|
|
[Test]
|
|
[TestRequiresDotsDebugOrCollectionChecks]
|
|
public unsafe void FixedList512Bytes_TestInterfaces() => TestInterfaces(new FixedList512Bytes<int>());
|
|
|
|
[Test]
|
|
[TestRequiresDotsDebugOrCollectionChecks]
|
|
public unsafe void FixedList4096Bytes_TestInterfaces() => TestInterfaces(new FixedList4096Bytes<int>());
|
|
}
|