
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     TextTransform Samples/Packages/com.unity.collections/Unity.Collections.Tests/FixedListTests.tt
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using NUnit.Framework;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Collections.Tests;
#if !UNITY_DOTSRUNTIME        // DOTS-Runtime doesn't support UnityEngine
using UnityEngine;
#endif

internal class FixedListTests : CollectionsTestFixture
{
    struct NonComparableStruct
    {
        public int a;
    }

    struct DescendingComparer<T> : IComparer<T> where T : IComparable<T>
    {
        public int Compare(T x, T y) => y.CompareTo(x);
    }

    [Test]
    public void FixedList32BytesDebugView()
    {
        var list = new FixedList32Bytes<NonComparableStruct>();
        CollectionAssert.IsEmpty(new FixedList32BytesDebugView<NonComparableStruct>(list).Items);

        var reference = new []
        {
            new NonComparableStruct{ a = 123 },
            new NonComparableStruct{ a = 234 },
            new NonComparableStruct{ a = 345 },
        };

        list.Add(reference[0]);
        list.Add(reference[1]);
        list.Add(reference[2]);

        CollectionAssert.AreEqual(reference, new FixedList32BytesDebugView<NonComparableStruct>(list).Items);
    }

    [Test]
    public void FixedList64BytesDebugView()
    {
        var list = new FixedList64Bytes<NonComparableStruct>();
        CollectionAssert.IsEmpty(new FixedList64BytesDebugView<NonComparableStruct>(list).Items);

        var reference = new []
        {
            new NonComparableStruct{ a = 123 },
            new NonComparableStruct{ a = 234 },
            new NonComparableStruct{ a = 345 },
        };

        list.Add(reference[0]);
        list.Add(reference[1]);
        list.Add(reference[2]);

        CollectionAssert.AreEqual(reference, new FixedList64BytesDebugView<NonComparableStruct>(list).Items);
    }

    [Test]
    public void FixedList128BytesDebugView()
    {
        var list = new FixedList128Bytes<NonComparableStruct>();
        CollectionAssert.IsEmpty(new FixedList128BytesDebugView<NonComparableStruct>(list).Items);

        var reference = new []
        {
            new NonComparableStruct{ a = 123 },
            new NonComparableStruct{ a = 234 },
            new NonComparableStruct{ a = 345 },
        };

        list.Add(reference[0]);
        list.Add(reference[1]);
        list.Add(reference[2]);

        CollectionAssert.AreEqual(reference, new FixedList128BytesDebugView<NonComparableStruct>(list).Items);
    }


    public readonly unsafe struct FixedList32Byte_Wrapper
    {
        readonly FixedList32Bytes<byte> _values;
        internal byte* Values => (byte*)_values.Buffer;
        public FixedList32Byte_Wrapper(byte x, byte y)
        {
            _values = new FixedList32Bytes<byte>();
            _values.Add(x);
            _values.Add(y);
            _values.Sort();
        }
    }

    unsafe void FixedList32Byte_ReadonlyWorksFunc1(in FixedList32Byte_Wrapper list, byte* originalValues)
    {
        byte* values = list.Values;
        Assert.AreEqual(originalValues[0], values[0], "Values[0] mismatch in func1");
        Assert.AreEqual(originalValues[1], values[1], "Values[1] mismatch in func1");
        Assert.AreEqual((ulong)originalValues, (ulong)values, "Buffer pointer mismatch in func1");
    }

    [Test]
    public unsafe void FixedList32Byte_ReadonlyWorks()
    {
        var list = new FixedList32Byte_Wrapper(17, 23);
        byte* values = list.Values;
        FixedList32Byte_ReadonlyWorksFunc1(list, values);
    }

    [Test]
    public void FixedList32Byte_FixedBytes32Align8ToNativeArrayWorksGeneric()
    {
        var list = new FixedList<byte,FixedBytes32Align8>();

        for(var i = 0; i < 30; ++i)
            list.Add((byte)(i * 123 + 234));

        using(var array = list.ToNativeArray(Allocator.Temp))
        {
            for(var i = 0; i < 30; ++i)
                Assert.AreEqual((byte)(i * 123 + 234), array[i]);
        }
    }

    [Test]
    public void FixedList32Byte_ToNativeArrayWorks()
    {
        var list = new FixedList32Bytes<byte>();

        for(var i = 0; i < 30; ++i)
            list.Add((byte)(i * 123 + 234));

        using(var array = list.ToNativeArray(Allocator.Temp))
        {
            for(var i = 0; i < 30; ++i)
                Assert.AreEqual((byte)(i * 123 + 234), array[i]);
        }
    }

    [Test]
    public void FixedList32Byte_GenericHasExpectedLayout()
    {
        var actual = new FixedList32Bytes<byte>();
        for(var i = 0; i < 30; ++i)
          actual.Add((byte)i);
        unsafe
        {
            var e = stackalloc byte[32];
            e[0] = (byte)((30 >> 0) & 0xFF);
            e[1] = (byte)((30 >> 8) & 0xFF);
            for(var i = 0; i < 30; ++i)
            {
              var s = (byte)i;
              UnsafeUtility.MemCpy(e + 2 + FixedList.PaddingBytes<byte>() + sizeof(byte) * i, &s, sizeof(byte));
            }
            Assert.AreEqual(0, UnsafeUtility.MemCmp(e, &actual.data, 32));
        }
    }

    [Test]
    [TestRequiresDotsDebugOrCollectionChecks]
    public void FixedList32Byte_GenericHasExpectedCapacity()
    {
        var list = new FixedList32Bytes<byte>();
        var expectedCapacity = list.Capacity;
        for(int i = 0; i < expectedCapacity; ++i)
            list.Add((byte)i);

        Assert.Throws<IndexOutOfRangeException> (() => { list.Add((byte)expectedCapacity); });
    }
    [Test]
    public unsafe void FixedList32Byte_GenericAdd()
    {
        var list = new FixedList32Bytes<byte>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.Add((byte)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.Add(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList32Byte_GenericAddRange()
    {
        var list = new FixedList32Bytes<byte>();
        var capacity = list.Capacity;
        var items = stackalloc byte[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (byte)i;

        var half = capacity / 2;
        list.AddRange(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRange(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList32Byte_GenericAddNoResize()
    {
        var list = new FixedList32Bytes<byte>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.AddNoResize((byte)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddNoResize(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList32Byte_GenericAddRangeNoResize()
    {
        var list = new FixedList32Bytes<byte>();
        var capacity = list.Capacity;
        var items = stackalloc byte[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (byte)i;

        var half = capacity / 2;
        list.AddRangeNoResize(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRangeNoResize(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList32Byte_GenericAddReplicate()
    {
        var list = new FixedList32Bytes<byte>();
        list.AddReplicate(42, 2);
        Assert.AreEqual(2, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

        list.AddReplicate(42, 3);
        Assert.AreEqual(5, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddReplicate(42, 1000); });
#endif
        Assert.AreEqual(5, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList32Byte_GenericInsertRangeWithBeginEnd()
    {
        var list = new FixedList32Bytes<byte>() { 0, 3, 4 };
        list.InsertRangeWithBeginEnd(1,3);
        list[1] = 1;
        list[2] = 2;
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Byte_GenericInsertRange()
    {
        var list = new FixedList32Bytes<byte>() { 0, 3, 4 };
        Assert.AreEqual(3, list.Length);

        list.InsertRange(1, 2);
        Assert.AreEqual(5, list.Length);
        list[1] = 1;
        list[2] = 2;

        Assert.DoesNotThrow(() => list.InsertRange(1, 0));
        Assert.AreEqual(5, list.Length);

        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Byte_GenericRemoveRange()
    {
        var list = new FixedList32Bytes<byte>() { 0, 3, 3, 1, 2 };
        list.RemoveRange(1, 2);
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Byte_GenericInsert()
    {
        var list = new FixedList32Bytes<byte>() { 0, 3, 4 };
        list.Insert(1,1);
        list.Insert(2,2);
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Byte_GenericRemoveAt()
    {
        var list = new FixedList32Bytes<byte>() { 0, 3, 3, 1, 2 };
        list.RemoveAt(1);
        list.RemoveAt(1);
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Byte_GenericRemove()
    {
        var list = new FixedList32Bytes<byte>() { 0, 3, 3, 1, 2 };
        Assert.True(list.Remove((byte)3));
        Assert.True(list.Remove((byte)3));
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Byte_GenericRemoveSwapBack()
    {
        var list = new FixedList32Bytes<byte>() { 0, 3, 3, 2, 1 };
        Assert.True(list.RemoveSwapBack((byte)3));
        Assert.True(list.RemoveSwapBack((byte)3));
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Byte_GenericSort()
    {
        var list = new FixedList32Bytes<byte>();
        for(var i = 0; i < 5; ++i)
          list.Add((byte)(4-i));
        list.Sort();
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Byte_GenericSortCustomComparer()
    {
        var list = new FixedList32Bytes<byte>();
        for(var i = 0; i < 5; ++i)
          list.Add((byte)(i));
        list.Sort(new DescendingComparer<byte>());
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(4-i, list[i]);
    }

    [Test]
    public unsafe void FixedList32Byte_IndexOf()
    {
        var list = new FixedList32Bytes<byte>() { 123, 178 };
        bool r0 = false, r1 = false, r2 = false;

        GCAllocRecorder.ValidateNoGCAllocs(() =>
        {
            r0 = -1 != list.IndexOf((byte)145);
            r1 = list.Contains((byte)123);
            r2 = list.Contains((byte)178);
        });

        Assert.False(r0);
        Assert.True(r1);
        Assert.True(r2);
    }


    public readonly unsafe struct FixedList64Byte_Wrapper
    {
        readonly FixedList64Bytes<byte> _values;
        internal byte* Values => (byte*)_values.Buffer;
        public FixedList64Byte_Wrapper(byte x, byte y)
        {
            _values = new FixedList64Bytes<byte>();
            _values.Add(x);
            _values.Add(y);
            _values.Sort();
        }
    }

    unsafe void FixedList64Byte_ReadonlyWorksFunc1(in FixedList64Byte_Wrapper list, byte* originalValues)
    {
        byte* values = list.Values;
        Assert.AreEqual(originalValues[0], values[0], "Values[0] mismatch in func1");
        Assert.AreEqual(originalValues[1], values[1], "Values[1] mismatch in func1");
        Assert.AreEqual((ulong)originalValues, (ulong)values, "Buffer pointer mismatch in func1");
    }

    [Test]
    public unsafe void FixedList64Byte_ReadonlyWorks()
    {
        var list = new FixedList64Byte_Wrapper(17, 23);
        byte* values = list.Values;
        FixedList64Byte_ReadonlyWorksFunc1(list, values);
    }

    [Test]
    public void FixedList64Byte_FixedBytes64Align8ToNativeArrayWorksGeneric()
    {
        var list = new FixedList<byte,FixedBytes64Align8>();

        for(var i = 0; i < 62; ++i)
            list.Add((byte)(i * 123 + 234));

        using(var array = list.ToNativeArray(Allocator.Temp))
        {
            for(var i = 0; i < 62; ++i)
                Assert.AreEqual((byte)(i * 123 + 234), array[i]);
        }
    }

    [Test]
    public void FixedList64Byte_ToNativeArrayWorks()
    {
        var list = new FixedList64Bytes<byte>();

        for(var i = 0; i < 62; ++i)
            list.Add((byte)(i * 123 + 234));

        using(var array = list.ToNativeArray(Allocator.Temp))
        {
            for(var i = 0; i < 62; ++i)
                Assert.AreEqual((byte)(i * 123 + 234), array[i]);
        }
    }

    [Test]
    public void FixedList64Byte_GenericHasExpectedLayout()
    {
        var actual = new FixedList64Bytes<byte>();
        for(var i = 0; i < 62; ++i)
          actual.Add((byte)i);
        unsafe
        {
            var e = stackalloc byte[64];
            e[0] = (byte)((62 >> 0) & 0xFF);
            e[1] = (byte)((62 >> 8) & 0xFF);
            for(var i = 0; i < 62; ++i)
            {
              var s = (byte)i;
              UnsafeUtility.MemCpy(e + 2 + FixedList.PaddingBytes<byte>() + sizeof(byte) * i, &s, sizeof(byte));
            }
            Assert.AreEqual(0, UnsafeUtility.MemCmp(e, &actual.data, 64));
        }
    }

    [Test]
    [TestRequiresDotsDebugOrCollectionChecks]
    public void FixedList64Byte_GenericHasExpectedCapacity()
    {
        var list = new FixedList64Bytes<byte>();
        var expectedCapacity = list.Capacity;
        for(int i = 0; i < expectedCapacity; ++i)
            list.Add((byte)i);

        Assert.Throws<IndexOutOfRangeException> (() => { list.Add((byte)expectedCapacity); });
    }
    [Test]
    public unsafe void FixedList64Byte_GenericAdd()
    {
        var list = new FixedList64Bytes<byte>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.Add((byte)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.Add(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList64Byte_GenericAddRange()
    {
        var list = new FixedList64Bytes<byte>();
        var capacity = list.Capacity;
        var items = stackalloc byte[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (byte)i;

        var half = capacity / 2;
        list.AddRange(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRange(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList64Byte_GenericAddNoResize()
    {
        var list = new FixedList64Bytes<byte>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.AddNoResize((byte)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddNoResize(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList64Byte_GenericAddRangeNoResize()
    {
        var list = new FixedList64Bytes<byte>();
        var capacity = list.Capacity;
        var items = stackalloc byte[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (byte)i;

        var half = capacity / 2;
        list.AddRangeNoResize(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRangeNoResize(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList64Byte_GenericAddReplicate()
    {
        var list = new FixedList64Bytes<byte>();
        list.AddReplicate(42, 2);
        Assert.AreEqual(2, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

        list.AddReplicate(42, 3);
        Assert.AreEqual(5, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddReplicate(42, 1000); });
#endif
        Assert.AreEqual(5, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList64Byte_GenericInsertRangeWithBeginEnd()
    {
        var list = new FixedList64Bytes<byte>() { 0, 3, 4 };
        list.InsertRangeWithBeginEnd(1,3);
        list[1] = 1;
        list[2] = 2;
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Byte_GenericInsertRange()
    {
        var list = new FixedList64Bytes<byte>() { 0, 3, 4 };
        Assert.AreEqual(3, list.Length);

        list.InsertRange(1, 2);
        Assert.AreEqual(5, list.Length);
        list[1] = 1;
        list[2] = 2;

        Assert.DoesNotThrow(() => list.InsertRange(1, 0));
        Assert.AreEqual(5, list.Length);

        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Byte_GenericRemoveRange()
    {
        var list = new FixedList64Bytes<byte>() { 0, 3, 3, 1, 2 };
        list.RemoveRange(1, 2);
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Byte_GenericInsert()
    {
        var list = new FixedList64Bytes<byte>() { 0, 3, 4 };
        list.Insert(1,1);
        list.Insert(2,2);
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Byte_GenericRemoveAt()
    {
        var list = new FixedList64Bytes<byte>() { 0, 3, 3, 1, 2 };
        list.RemoveAt(1);
        list.RemoveAt(1);
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Byte_GenericRemove()
    {
        var list = new FixedList64Bytes<byte>() { 0, 3, 3, 1, 2 };
        Assert.True(list.Remove((byte)3));
        Assert.True(list.Remove((byte)3));
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Byte_GenericRemoveSwapBack()
    {
        var list = new FixedList64Bytes<byte>() { 0, 3, 3, 2, 1 };
        Assert.True(list.RemoveSwapBack((byte)3));
        Assert.True(list.RemoveSwapBack((byte)3));
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Byte_GenericSort()
    {
        var list = new FixedList64Bytes<byte>();
        for(var i = 0; i < 5; ++i)
          list.Add((byte)(4-i));
        list.Sort();
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Byte_GenericSortCustomComparer()
    {
        var list = new FixedList64Bytes<byte>();
        for(var i = 0; i < 5; ++i)
          list.Add((byte)(i));
        list.Sort(new DescendingComparer<byte>());
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(4-i, list[i]);
    }

    [Test]
    public unsafe void FixedList64Byte_IndexOf()
    {
        var list = new FixedList64Bytes<byte>() { 123, 178 };
        bool r0 = false, r1 = false, r2 = false;

        GCAllocRecorder.ValidateNoGCAllocs(() =>
        {
            r0 = -1 != list.IndexOf((byte)145);
            r1 = list.Contains((byte)123);
            r2 = list.Contains((byte)178);
        });

        Assert.False(r0);
        Assert.True(r1);
        Assert.True(r2);
    }


    public readonly unsafe struct FixedList128Byte_Wrapper
    {
        readonly FixedList128Bytes<byte> _values;
        internal byte* Values => (byte*)_values.Buffer;
        public FixedList128Byte_Wrapper(byte x, byte y)
        {
            _values = new FixedList128Bytes<byte>();
            _values.Add(x);
            _values.Add(y);
            _values.Sort();
        }
    }

    unsafe void FixedList128Byte_ReadonlyWorksFunc1(in FixedList128Byte_Wrapper list, byte* originalValues)
    {
        byte* values = list.Values;
        Assert.AreEqual(originalValues[0], values[0], "Values[0] mismatch in func1");
        Assert.AreEqual(originalValues[1], values[1], "Values[1] mismatch in func1");
        Assert.AreEqual((ulong)originalValues, (ulong)values, "Buffer pointer mismatch in func1");
    }

    [Test]
    public unsafe void FixedList128Byte_ReadonlyWorks()
    {
        var list = new FixedList128Byte_Wrapper(17, 23);
        byte* values = list.Values;
        FixedList128Byte_ReadonlyWorksFunc1(list, values);
    }

    [Test]
    public void FixedList128Byte_FixedBytes128Align8ToNativeArrayWorksGeneric()
    {
        var list = new FixedList<byte,FixedBytes128Align8>();

        for(var i = 0; i < 126; ++i)
            list.Add((byte)(i * 123 + 234));

        using(var array = list.ToNativeArray(Allocator.Temp))
        {
            for(var i = 0; i < 126; ++i)
                Assert.AreEqual((byte)(i * 123 + 234), array[i]);
        }
    }

    [Test]
    public void FixedList128Byte_ToNativeArrayWorks()
    {
        var list = new FixedList128Bytes<byte>();

        for(var i = 0; i < 126; ++i)
            list.Add((byte)(i * 123 + 234));

        using(var array = list.ToNativeArray(Allocator.Temp))
        {
            for(var i = 0; i < 126; ++i)
                Assert.AreEqual((byte)(i * 123 + 234), array[i]);
        }
    }

    [Test]
    public void FixedList128Byte_GenericHasExpectedLayout()
    {
        var actual = new FixedList128Bytes<byte>();
        for(var i = 0; i < 126; ++i)
          actual.Add((byte)i);
        unsafe
        {
            var e = stackalloc byte[128];
            e[0] = (byte)((126 >> 0) & 0xFF);
            e[1] = (byte)((126 >> 8) & 0xFF);
            for(var i = 0; i < 126; ++i)
            {
              var s = (byte)i;
              UnsafeUtility.MemCpy(e + 2 + FixedList.PaddingBytes<byte>() + sizeof(byte) * i, &s, sizeof(byte));
            }
            Assert.AreEqual(0, UnsafeUtility.MemCmp(e, &actual.data, 128));
        }
    }

    [Test]
    [TestRequiresDotsDebugOrCollectionChecks]
    public void FixedList128Byte_GenericHasExpectedCapacity()
    {
        var list = new FixedList128Bytes<byte>();
        var expectedCapacity = list.Capacity;
        for(int i = 0; i < expectedCapacity; ++i)
            list.Add((byte)i);

        Assert.Throws<IndexOutOfRangeException> (() => { list.Add((byte)expectedCapacity); });
    }
    [Test]
    public unsafe void FixedList128Byte_GenericAdd()
    {
        var list = new FixedList128Bytes<byte>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.Add((byte)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.Add(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList128Byte_GenericAddRange()
    {
        var list = new FixedList128Bytes<byte>();
        var capacity = list.Capacity;
        var items = stackalloc byte[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (byte)i;

        var half = capacity / 2;
        list.AddRange(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRange(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList128Byte_GenericAddNoResize()
    {
        var list = new FixedList128Bytes<byte>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.AddNoResize((byte)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddNoResize(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList128Byte_GenericAddRangeNoResize()
    {
        var list = new FixedList128Bytes<byte>();
        var capacity = list.Capacity;
        var items = stackalloc byte[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (byte)i;

        var half = capacity / 2;
        list.AddRangeNoResize(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRangeNoResize(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList128Byte_GenericAddReplicate()
    {
        var list = new FixedList128Bytes<byte>();
        list.AddReplicate(42, 2);
        Assert.AreEqual(2, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

        list.AddReplicate(42, 3);
        Assert.AreEqual(5, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddReplicate(42, 1000); });
#endif
        Assert.AreEqual(5, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList128Byte_GenericInsertRangeWithBeginEnd()
    {
        var list = new FixedList128Bytes<byte>() { 0, 3, 4 };
        list.InsertRangeWithBeginEnd(1,3);
        list[1] = 1;
        list[2] = 2;
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Byte_GenericInsertRange()
    {
        var list = new FixedList128Bytes<byte>() { 0, 3, 4 };
        Assert.AreEqual(3, list.Length);

        list.InsertRange(1, 2);
        Assert.AreEqual(5, list.Length);
        list[1] = 1;
        list[2] = 2;

        Assert.DoesNotThrow(() => list.InsertRange(1, 0));
        Assert.AreEqual(5, list.Length);

        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Byte_GenericRemoveRange()
    {
        var list = new FixedList128Bytes<byte>() { 0, 3, 3, 1, 2 };
        list.RemoveRange(1, 2);
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Byte_GenericInsert()
    {
        var list = new FixedList128Bytes<byte>() { 0, 3, 4 };
        list.Insert(1,1);
        list.Insert(2,2);
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Byte_GenericRemoveAt()
    {
        var list = new FixedList128Bytes<byte>() { 0, 3, 3, 1, 2 };
        list.RemoveAt(1);
        list.RemoveAt(1);
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Byte_GenericRemove()
    {
        var list = new FixedList128Bytes<byte>() { 0, 3, 3, 1, 2 };
        Assert.True(list.Remove((byte)3));
        Assert.True(list.Remove((byte)3));
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Byte_GenericRemoveSwapBack()
    {
        var list = new FixedList128Bytes<byte>() { 0, 3, 3, 2, 1 };
        Assert.True(list.RemoveSwapBack((byte)3));
        Assert.True(list.RemoveSwapBack((byte)3));
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Byte_GenericSort()
    {
        var list = new FixedList128Bytes<byte>();
        for(var i = 0; i < 5; ++i)
          list.Add((byte)(4-i));
        list.Sort();
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Byte_GenericSortCustomComparer()
    {
        var list = new FixedList128Bytes<byte>();
        for(var i = 0; i < 5; ++i)
          list.Add((byte)(i));
        list.Sort(new DescendingComparer<byte>());
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(4-i, list[i]);
    }

    [Test]
    public unsafe void FixedList128Byte_IndexOf()
    {
        var list = new FixedList128Bytes<byte>() { 123, 178 };
        bool r0 = false, r1 = false, r2 = false;

        GCAllocRecorder.ValidateNoGCAllocs(() =>
        {
            r0 = -1 != list.IndexOf((byte)145);
            r1 = list.Contains((byte)123);
            r2 = list.Contains((byte)178);
        });

        Assert.False(r0);
        Assert.True(r1);
        Assert.True(r2);
    }


    [Test]
    public void FixedList32Byte_HasExpectedLayout()
    {
        var actual = new FixedList32Bytes<byte>();
        for(var i = 0; i < 30; ++i)
          actual.Add((byte)i);
        unsafe
        {
            var e = stackalloc byte[32];
            e[0] = (byte)((30 >> 0) & 0xFF);
            e[1] = (byte)((30 >> 8) & 0xFF);
            for(var i = 0; i < 30; ++i)
            {
              var s = (byte)i;
              UnsafeUtility.MemCpy(e + 2 + FixedList.PaddingBytes<byte>() + sizeof(byte) * i, &s, sizeof(byte));
            }
            Assert.AreEqual(0, UnsafeUtility.MemCmp(e, &actual.data, 32));
        }
    }

    [Test]
    [TestRequiresDotsDebugOrCollectionChecks]
    public void FixedList32Byte_HasExpectedCapacity()
    {
        var list = new FixedList32Bytes<byte>();
        var expectedCapacity = list.Capacity;
        for(int i = 0; i < expectedCapacity; ++i)
            list.Add((byte)i);

        Assert.Throws<IndexOutOfRangeException> (() => { list.Add((byte)expectedCapacity); });
    }

#if !UNITY_DOTSRUNTIME        // DOTS-Runtime doesn't support UnityEngine
    class ScriptableObjectFixedList32Byte_ : UnityEngine.ScriptableObject
    {
        public FixedList32Bytes<byte> List;
    }

    [Test]
    public void FixedList32Byte_Serializes()
    {
        var a = UnityEngine.ScriptableObject.CreateInstance<ScriptableObjectFixedList32Byte_ >();
        for(int i = 0; i < a.List.Capacity; ++i)
            a.List.Add((byte)i);
        var b = UnityEngine.Object.Instantiate(a);
        CollectionAssert.AreEqual(a.List, b.List);
    }
#endif

    [Test]
    public unsafe void FixedList32Byte_Add()
    {
        var list = new FixedList32Bytes<byte>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.Add((byte)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.Add(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList32Byte_AddRange()
    {
        var list = new FixedList32Bytes<byte>();
        var capacity = list.Capacity;
        var items = stackalloc byte[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (byte)i;

        var half = capacity / 2;
        list.AddRange(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRange(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList32Byte_AddNoResize()
    {
        var list = new FixedList32Bytes<byte>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.AddNoResize((byte)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddNoResize(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList32Byte_AddRangeNoResize()
    {
        var list = new FixedList32Bytes<byte>();
        var capacity = list.Capacity;
        var items = stackalloc byte[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (byte)i;

        var half = capacity / 2;
        list.AddRangeNoResize(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRangeNoResize(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList32Byte_AddReplicate()
    {
        var list = new FixedList32Bytes<byte>();
        list.AddReplicate(42, 2);
        Assert.AreEqual(2, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

        list.AddReplicate(42, 3);
        Assert.AreEqual(5, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddReplicate(42, 1000); });
#endif
        Assert.AreEqual(5, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList32Byte_InsertRangeWithBeginEnd()
    {
        var list = new FixedList32Bytes<byte>() { 0, 3, 4 };
        list.InsertRangeWithBeginEnd(1,3);
        list[1] = 1;
        list[2] = 2;
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Byte_InsertRange()
    {
        var list = new FixedList32Bytes<byte>() { 0, 3, 4 };
        Assert.AreEqual(3, list.Length);

        list.InsertRange(1, 2);
        Assert.AreEqual(5, list.Length);
        list[1] = 1;
        list[2] = 2;

        Assert.DoesNotThrow(() => list.InsertRange(1, 0));
        Assert.AreEqual(5, list.Length);

        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    private static void Expected(ref FixedList32Bytes<byte> container, int expectedLength, int[] expected)
    {
        Assert.AreEqual(expectedLength == 0, container.IsEmpty);
        Assert.AreEqual(container.Length, expectedLength);
        for (var i = 0; i < container.Length; ++i)
        {
            Assert.AreEqual(expected[i], container[i]);
        }
    }

    [Test]
    public void FixedList32Byte_RemoveAt()
    {
        var list = new FixedList32Bytes<byte>() { 0, 3, 3, 1, 2 };
        list.RemoveAt(1);
        list.RemoveAt(1);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList32Byte_Remove()
    {
        var list = new FixedList32Bytes<byte>() { 0, 3, 3, 1, 2 };
        Assert.True(list.Remove((byte)3));
        Assert.True(list.Remove((byte)3));
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList32Byte_RemoveSwapBack()
    {
        var list = new FixedList32Bytes<byte>() { 0, 3, 3, 2, 1 };
        Assert.True(list.RemoveSwapBack((byte)3));
        Assert.True(list.RemoveSwapBack((byte)3));
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList32Byte_RemoveRange()
    {
        var list = new FixedList32Bytes<byte>() { 0, 3, 3, 1, 2 };
        list.RemoveRange(1, 2);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList32Byte_RemoveAtSwapBack()
    {
        var list = new FixedList32Bytes<byte>() { 0, 3, 3, 1, 2 };
        list.RemoveAtSwapBack(1);
        list.RemoveAtSwapBack(1);
        Expected(ref list, 3, new int[] { 0, 1, 3 });
    }

    [Test]
    public void FixedList32Byte_RemoveRangeSwapBack()
    {
        var list = new FixedList32Bytes<byte>() { 0, 3, 3, 1, 2 };
        list.RemoveRangeSwapBack(1, 2);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList32Byte_Insert()
    {
        var list = new FixedList32Bytes<byte>() { 0, 3, 4 };
        list.Insert(1,1);
        list.Insert(2,2);
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public unsafe void FixedList32Byte_Unaligned_Read_Write()
    {
        int alignment = UnsafeUtility.AlignOf<byte>();
        if(alignment == 1)
            return;

        // Create a unaligned FixedList32Bytes<byte> and ensure we can still read+write safely
        const int buffSize = 32 * 2;
        byte* buff = stackalloc byte[buffSize];
        UnsafeUtility.MemSet(buff, 0xCD, buffSize);

        int offset = 0;
        while (CollectionHelper.IsAligned((ulong)buff + (ulong)offset, alignment))
            offset++;
        ulong unalignedBuff = (ulong)buff + (ulong)offset;

        var list = (FixedList32Bytes<byte>*)(unalignedBuff);
        list->Length = 0;

        for (var i = 0; i < 30; ++i)
            list->Add((byte)i);

        for (var i = 0; i < 30; ++i)
            Assert.AreEqual(i, list->ElementAt(i));

        // Ensure we didn't write outside of our fixed list byte range
        for(int i = UnsafeUtility.SizeOf<FixedList32Bytes<byte>>() + offset; i < buffSize; ++i)
            Assert.AreEqual(buff[i], 0xCD);
    }

    [Test]
    public void FixedList32Byte_Sort()
    {
        var list = new FixedList32Bytes<byte>();
        for(var i = 0; i < 5; ++i)
          list.Add((byte)(4-i));
        list.Sort();
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Byte_To_FixedList64Byte()
    {
        var a = new FixedList32Bytes<byte>();
        for(var i = 0; i < 30; ++i)
            a.Add((byte)i);
        var b = new FixedList64Bytes<byte>(a);
        for(var i = 0; i < 30; ++i)
            Assert.AreEqual((byte)i, b[i]);
    }
    [Test]
    public void FixedList32Byte_To_FixedList128Byte()
    {
        var a = new FixedList32Bytes<byte>();
        for(var i = 0; i < 30; ++i)
            a.Add((byte)i);
        var b = new FixedList128Bytes<byte>(a);
        for(var i = 0; i < 30; ++i)
            Assert.AreEqual((byte)i, b[i]);
    }

    [Test]
    public void FixedList64Byte_HasExpectedLayout()
    {
        var actual = new FixedList64Bytes<byte>();
        for(var i = 0; i < 62; ++i)
          actual.Add((byte)i);
        unsafe
        {
            var e = stackalloc byte[64];
            e[0] = (byte)((62 >> 0) & 0xFF);
            e[1] = (byte)((62 >> 8) & 0xFF);
            for(var i = 0; i < 62; ++i)
            {
              var s = (byte)i;
              UnsafeUtility.MemCpy(e + 2 + FixedList.PaddingBytes<byte>() + sizeof(byte) * i, &s, sizeof(byte));
            }
            Assert.AreEqual(0, UnsafeUtility.MemCmp(e, &actual.data, 64));
        }
    }

    [Test]
    [TestRequiresDotsDebugOrCollectionChecks]
    public void FixedList64Byte_HasExpectedCapacity()
    {
        var list = new FixedList64Bytes<byte>();
        var expectedCapacity = list.Capacity;
        for(int i = 0; i < expectedCapacity; ++i)
            list.Add((byte)i);

        Assert.Throws<IndexOutOfRangeException> (() => { list.Add((byte)expectedCapacity); });
    }

#if !UNITY_DOTSRUNTIME        // DOTS-Runtime doesn't support UnityEngine
    class ScriptableObjectFixedList64Byte_ : UnityEngine.ScriptableObject
    {
        public FixedList64Bytes<byte> List;
    }

    [Test]
    public void FixedList64Byte_Serializes()
    {
        var a = UnityEngine.ScriptableObject.CreateInstance<ScriptableObjectFixedList64Byte_ >();
        for(int i = 0; i < a.List.Capacity; ++i)
            a.List.Add((byte)i);
        var b = UnityEngine.Object.Instantiate(a);
        CollectionAssert.AreEqual(a.List, b.List);
    }
#endif

    [Test]
    public unsafe void FixedList64Byte_Add()
    {
        var list = new FixedList64Bytes<byte>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.Add((byte)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.Add(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList64Byte_AddRange()
    {
        var list = new FixedList64Bytes<byte>();
        var capacity = list.Capacity;
        var items = stackalloc byte[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (byte)i;

        var half = capacity / 2;
        list.AddRange(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRange(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList64Byte_AddNoResize()
    {
        var list = new FixedList64Bytes<byte>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.AddNoResize((byte)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddNoResize(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList64Byte_AddRangeNoResize()
    {
        var list = new FixedList64Bytes<byte>();
        var capacity = list.Capacity;
        var items = stackalloc byte[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (byte)i;

        var half = capacity / 2;
        list.AddRangeNoResize(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRangeNoResize(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList64Byte_AddReplicate()
    {
        var list = new FixedList64Bytes<byte>();
        list.AddReplicate(42, 2);
        Assert.AreEqual(2, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

        list.AddReplicate(42, 3);
        Assert.AreEqual(5, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddReplicate(42, 1000); });
#endif
        Assert.AreEqual(5, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList64Byte_InsertRangeWithBeginEnd()
    {
        var list = new FixedList64Bytes<byte>() { 0, 3, 4 };
        list.InsertRangeWithBeginEnd(1,3);
        list[1] = 1;
        list[2] = 2;
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Byte_InsertRange()
    {
        var list = new FixedList64Bytes<byte>() { 0, 3, 4 };
        Assert.AreEqual(3, list.Length);

        list.InsertRange(1, 2);
        Assert.AreEqual(5, list.Length);
        list[1] = 1;
        list[2] = 2;

        Assert.DoesNotThrow(() => list.InsertRange(1, 0));
        Assert.AreEqual(5, list.Length);

        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    private static void Expected(ref FixedList64Bytes<byte> container, int expectedLength, int[] expected)
    {
        Assert.AreEqual(expectedLength == 0, container.IsEmpty);
        Assert.AreEqual(container.Length, expectedLength);
        for (var i = 0; i < container.Length; ++i)
        {
            Assert.AreEqual(expected[i], container[i]);
        }
    }

    [Test]
    public void FixedList64Byte_RemoveAt()
    {
        var list = new FixedList64Bytes<byte>() { 0, 3, 3, 1, 2 };
        list.RemoveAt(1);
        list.RemoveAt(1);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList64Byte_Remove()
    {
        var list = new FixedList64Bytes<byte>() { 0, 3, 3, 1, 2 };
        Assert.True(list.Remove((byte)3));
        Assert.True(list.Remove((byte)3));
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList64Byte_RemoveSwapBack()
    {
        var list = new FixedList64Bytes<byte>() { 0, 3, 3, 2, 1 };
        Assert.True(list.RemoveSwapBack((byte)3));
        Assert.True(list.RemoveSwapBack((byte)3));
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList64Byte_RemoveRange()
    {
        var list = new FixedList64Bytes<byte>() { 0, 3, 3, 1, 2 };
        list.RemoveRange(1, 2);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList64Byte_RemoveAtSwapBack()
    {
        var list = new FixedList64Bytes<byte>() { 0, 3, 3, 1, 2 };
        list.RemoveAtSwapBack(1);
        list.RemoveAtSwapBack(1);
        Expected(ref list, 3, new int[] { 0, 1, 3 });
    }

    [Test]
    public void FixedList64Byte_RemoveRangeSwapBack()
    {
        var list = new FixedList64Bytes<byte>() { 0, 3, 3, 1, 2 };
        list.RemoveRangeSwapBack(1, 2);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList64Byte_Insert()
    {
        var list = new FixedList64Bytes<byte>() { 0, 3, 4 };
        list.Insert(1,1);
        list.Insert(2,2);
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public unsafe void FixedList64Byte_Unaligned_Read_Write()
    {
        int alignment = UnsafeUtility.AlignOf<byte>();
        if(alignment == 1)
            return;

        // Create a unaligned FixedList64Bytes<byte> and ensure we can still read+write safely
        const int buffSize = 64 * 2;
        byte* buff = stackalloc byte[buffSize];
        UnsafeUtility.MemSet(buff, 0xCD, buffSize);

        int offset = 0;
        while (CollectionHelper.IsAligned((ulong)buff + (ulong)offset, alignment))
            offset++;
        ulong unalignedBuff = (ulong)buff + (ulong)offset;

        var list = (FixedList64Bytes<byte>*)(unalignedBuff);
        list->Length = 0;

        for (var i = 0; i < 62; ++i)
            list->Add((byte)i);

        for (var i = 0; i < 62; ++i)
            Assert.AreEqual(i, list->ElementAt(i));

        // Ensure we didn't write outside of our fixed list byte range
        for(int i = UnsafeUtility.SizeOf<FixedList64Bytes<byte>>() + offset; i < buffSize; ++i)
            Assert.AreEqual(buff[i], 0xCD);
    }

    [Test]
    public void FixedList64Byte_Sort()
    {
        var list = new FixedList64Bytes<byte>();
        for(var i = 0; i < 5; ++i)
          list.Add((byte)(4-i));
        list.Sort();
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Byte_To_FixedList32Byte()
    {
        var a = new FixedList64Bytes<byte>();
        for(var i = 0; i < 62; ++i)
            a.Add((byte)i);
#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException> (() => { var b = new FixedList32Bytes<byte>(a); } );
#endif
    }
    [Test]
    public void FixedList64Byte_To_FixedList128Byte()
    {
        var a = new FixedList64Bytes<byte>();
        for(var i = 0; i < 62; ++i)
            a.Add((byte)i);
        var b = new FixedList128Bytes<byte>(a);
        for(var i = 0; i < 62; ++i)
            Assert.AreEqual((byte)i, b[i]);
    }

    [Test]
    public void FixedList128Byte_HasExpectedLayout()
    {
        var actual = new FixedList128Bytes<byte>();
        for(var i = 0; i < 126; ++i)
          actual.Add((byte)i);
        unsafe
        {
            var e = stackalloc byte[128];
            e[0] = (byte)((126 >> 0) & 0xFF);
            e[1] = (byte)((126 >> 8) & 0xFF);
            for(var i = 0; i < 126; ++i)
            {
              var s = (byte)i;
              UnsafeUtility.MemCpy(e + 2 + FixedList.PaddingBytes<byte>() + sizeof(byte) * i, &s, sizeof(byte));
            }
            Assert.AreEqual(0, UnsafeUtility.MemCmp(e, &actual.data, 128));
        }
    }

    [Test]
    [TestRequiresDotsDebugOrCollectionChecks]
    public void FixedList128Byte_HasExpectedCapacity()
    {
        var list = new FixedList128Bytes<byte>();
        var expectedCapacity = list.Capacity;
        for(int i = 0; i < expectedCapacity; ++i)
            list.Add((byte)i);

        Assert.Throws<IndexOutOfRangeException> (() => { list.Add((byte)expectedCapacity); });
    }

#if !UNITY_DOTSRUNTIME        // DOTS-Runtime doesn't support UnityEngine
    class ScriptableObjectFixedList128Byte_ : UnityEngine.ScriptableObject
    {
        public FixedList128Bytes<byte> List;
    }

    [Test]
    public void FixedList128Byte_Serializes()
    {
        var a = UnityEngine.ScriptableObject.CreateInstance<ScriptableObjectFixedList128Byte_ >();
        for(int i = 0; i < a.List.Capacity; ++i)
            a.List.Add((byte)i);
        var b = UnityEngine.Object.Instantiate(a);
        CollectionAssert.AreEqual(a.List, b.List);
    }
#endif

    [Test]
    public unsafe void FixedList128Byte_Add()
    {
        var list = new FixedList128Bytes<byte>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.Add((byte)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.Add(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList128Byte_AddRange()
    {
        var list = new FixedList128Bytes<byte>();
        var capacity = list.Capacity;
        var items = stackalloc byte[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (byte)i;

        var half = capacity / 2;
        list.AddRange(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRange(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList128Byte_AddNoResize()
    {
        var list = new FixedList128Bytes<byte>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.AddNoResize((byte)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddNoResize(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList128Byte_AddRangeNoResize()
    {
        var list = new FixedList128Bytes<byte>();
        var capacity = list.Capacity;
        var items = stackalloc byte[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (byte)i;

        var half = capacity / 2;
        list.AddRangeNoResize(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRangeNoResize(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList128Byte_AddReplicate()
    {
        var list = new FixedList128Bytes<byte>();
        list.AddReplicate(42, 2);
        Assert.AreEqual(2, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

        list.AddReplicate(42, 3);
        Assert.AreEqual(5, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddReplicate(42, 1000); });
#endif
        Assert.AreEqual(5, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList128Byte_InsertRangeWithBeginEnd()
    {
        var list = new FixedList128Bytes<byte>() { 0, 3, 4 };
        list.InsertRangeWithBeginEnd(1,3);
        list[1] = 1;
        list[2] = 2;
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Byte_InsertRange()
    {
        var list = new FixedList128Bytes<byte>() { 0, 3, 4 };
        Assert.AreEqual(3, list.Length);

        list.InsertRange(1, 2);
        Assert.AreEqual(5, list.Length);
        list[1] = 1;
        list[2] = 2;

        Assert.DoesNotThrow(() => list.InsertRange(1, 0));
        Assert.AreEqual(5, list.Length);

        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    private static void Expected(ref FixedList128Bytes<byte> container, int expectedLength, int[] expected)
    {
        Assert.AreEqual(expectedLength == 0, container.IsEmpty);
        Assert.AreEqual(container.Length, expectedLength);
        for (var i = 0; i < container.Length; ++i)
        {
            Assert.AreEqual(expected[i], container[i]);
        }
    }

    [Test]
    public void FixedList128Byte_RemoveAt()
    {
        var list = new FixedList128Bytes<byte>() { 0, 3, 3, 1, 2 };
        list.RemoveAt(1);
        list.RemoveAt(1);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList128Byte_Remove()
    {
        var list = new FixedList128Bytes<byte>() { 0, 3, 3, 1, 2 };
        Assert.True(list.Remove((byte)3));
        Assert.True(list.Remove((byte)3));
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList128Byte_RemoveSwapBack()
    {
        var list = new FixedList128Bytes<byte>() { 0, 3, 3, 2, 1 };
        Assert.True(list.RemoveSwapBack((byte)3));
        Assert.True(list.RemoveSwapBack((byte)3));
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList128Byte_RemoveRange()
    {
        var list = new FixedList128Bytes<byte>() { 0, 3, 3, 1, 2 };
        list.RemoveRange(1, 2);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList128Byte_RemoveAtSwapBack()
    {
        var list = new FixedList128Bytes<byte>() { 0, 3, 3, 1, 2 };
        list.RemoveAtSwapBack(1);
        list.RemoveAtSwapBack(1);
        Expected(ref list, 3, new int[] { 0, 1, 3 });
    }

    [Test]
    public void FixedList128Byte_RemoveRangeSwapBack()
    {
        var list = new FixedList128Bytes<byte>() { 0, 3, 3, 1, 2 };
        list.RemoveRangeSwapBack(1, 2);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList128Byte_Insert()
    {
        var list = new FixedList128Bytes<byte>() { 0, 3, 4 };
        list.Insert(1,1);
        list.Insert(2,2);
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public unsafe void FixedList128Byte_Unaligned_Read_Write()
    {
        int alignment = UnsafeUtility.AlignOf<byte>();
        if(alignment == 1)
            return;

        // Create a unaligned FixedList128Bytes<byte> and ensure we can still read+write safely
        const int buffSize = 128 * 2;
        byte* buff = stackalloc byte[buffSize];
        UnsafeUtility.MemSet(buff, 0xCD, buffSize);

        int offset = 0;
        while (CollectionHelper.IsAligned((ulong)buff + (ulong)offset, alignment))
            offset++;
        ulong unalignedBuff = (ulong)buff + (ulong)offset;

        var list = (FixedList128Bytes<byte>*)(unalignedBuff);
        list->Length = 0;

        for (var i = 0; i < 126; ++i)
            list->Add((byte)i);

        for (var i = 0; i < 126; ++i)
            Assert.AreEqual(i, list->ElementAt(i));

        // Ensure we didn't write outside of our fixed list byte range
        for(int i = UnsafeUtility.SizeOf<FixedList128Bytes<byte>>() + offset; i < buffSize; ++i)
            Assert.AreEqual(buff[i], 0xCD);
    }

    [Test]
    public void FixedList128Byte_Sort()
    {
        var list = new FixedList128Bytes<byte>();
        for(var i = 0; i < 5; ++i)
          list.Add((byte)(4-i));
        list.Sort();
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Byte_To_FixedList32Byte()
    {
        var a = new FixedList128Bytes<byte>();
        for(var i = 0; i < 126; ++i)
            a.Add((byte)i);
#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException> (() => { var b = new FixedList32Bytes<byte>(a); } );
#endif
    }
    [Test]
    public void FixedList128Byte_To_FixedList64Byte()
    {
        var a = new FixedList128Bytes<byte>();
        for(var i = 0; i < 126; ++i)
            a.Add((byte)i);
#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException> (() => { var b = new FixedList64Bytes<byte>(a); } );
#endif
    }

    public readonly unsafe struct FixedList32Int_Wrapper
    {
        readonly FixedList32Bytes<int> _values;
        internal int* Values => (int*)_values.Buffer;
        public FixedList32Int_Wrapper(int x, int y)
        {
            _values = new FixedList32Bytes<int>();
            _values.Add(x);
            _values.Add(y);
            _values.Sort();
        }
    }

    unsafe void FixedList32Int_ReadonlyWorksFunc1(in FixedList32Int_Wrapper list, int* originalValues)
    {
        int* values = list.Values;
        Assert.AreEqual(originalValues[0], values[0], "Values[0] mismatch in func1");
        Assert.AreEqual(originalValues[1], values[1], "Values[1] mismatch in func1");
        Assert.AreEqual((ulong)originalValues, (ulong)values, "Buffer pointer mismatch in func1");
    }

    [Test]
    public unsafe void FixedList32Int_ReadonlyWorks()
    {
        var list = new FixedList32Int_Wrapper(17, 23);
        int* values = list.Values;
        FixedList32Int_ReadonlyWorksFunc1(list, values);
    }

    [Test]
    public void FixedList32Int_FixedBytes32Align8ToNativeArrayWorksGeneric()
    {
        var list = new FixedList<int,FixedBytes32Align8>();

        for(var i = 0; i < 7; ++i)
            list.Add((int)(i * 123 + 234));

        using(var array = list.ToNativeArray(Allocator.Temp))
        {
            for(var i = 0; i < 7; ++i)
                Assert.AreEqual((int)(i * 123 + 234), array[i]);
        }
    }

    [Test]
    public void FixedList32Int_ToNativeArrayWorks()
    {
        var list = new FixedList32Bytes<int>();

        for(var i = 0; i < 7; ++i)
            list.Add((int)(i * 123 + 234));

        using(var array = list.ToNativeArray(Allocator.Temp))
        {
            for(var i = 0; i < 7; ++i)
                Assert.AreEqual((int)(i * 123 + 234), array[i]);
        }
    }

    [Test]
    public void FixedList32Int_GenericHasExpectedLayout()
    {
        var actual = new FixedList32Bytes<int>();
        for(var i = 0; i < 7; ++i)
          actual.Add((int)i);
        unsafe
        {
            var e = stackalloc byte[32];
            e[0] = (byte)((7 >> 0) & 0xFF);
            e[1] = (byte)((7 >> 8) & 0xFF);
            for(var i = 0; i < 7; ++i)
            {
              var s = (int)i;
              UnsafeUtility.MemCpy(e + 2 + FixedList.PaddingBytes<int>() + sizeof(int) * i, &s, sizeof(int));
            }
            Assert.AreEqual(0, UnsafeUtility.MemCmp(e, &actual.data, 32));
        }
    }

    [Test]
    [TestRequiresDotsDebugOrCollectionChecks]
    public void FixedList32Int_GenericHasExpectedCapacity()
    {
        var list = new FixedList32Bytes<int>();
        var expectedCapacity = list.Capacity;
        for(int i = 0; i < expectedCapacity; ++i)
            list.Add((int)i);

        Assert.Throws<IndexOutOfRangeException> (() => { list.Add((int)expectedCapacity); });
    }
    [Test]
    public unsafe void FixedList32Int_GenericAdd()
    {
        var list = new FixedList32Bytes<int>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.Add((int)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.Add(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList32Int_GenericAddRange()
    {
        var list = new FixedList32Bytes<int>();
        var capacity = list.Capacity;
        var items = stackalloc int[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (int)i;

        var half = capacity / 2;
        list.AddRange(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRange(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList32Int_GenericAddNoResize()
    {
        var list = new FixedList32Bytes<int>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.AddNoResize((int)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddNoResize(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList32Int_GenericAddRangeNoResize()
    {
        var list = new FixedList32Bytes<int>();
        var capacity = list.Capacity;
        var items = stackalloc int[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (int)i;

        var half = capacity / 2;
        list.AddRangeNoResize(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRangeNoResize(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList32Int_GenericAddReplicate()
    {
        var list = new FixedList32Bytes<int>();
        list.AddReplicate(42, 2);
        Assert.AreEqual(2, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

        list.AddReplicate(42, 3);
        Assert.AreEqual(5, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddReplicate(42, 1000); });
#endif
        Assert.AreEqual(5, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList32Int_GenericInsertRangeWithBeginEnd()
    {
        var list = new FixedList32Bytes<int>() { 0, 3, 4 };
        list.InsertRangeWithBeginEnd(1,3);
        list[1] = 1;
        list[2] = 2;
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Int_GenericInsertRange()
    {
        var list = new FixedList32Bytes<int>() { 0, 3, 4 };
        Assert.AreEqual(3, list.Length);

        list.InsertRange(1, 2);
        Assert.AreEqual(5, list.Length);
        list[1] = 1;
        list[2] = 2;

        Assert.DoesNotThrow(() => list.InsertRange(1, 0));
        Assert.AreEqual(5, list.Length);

        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Int_GenericRemoveRange()
    {
        var list = new FixedList32Bytes<int>() { 0, 3, 3, 1, 2 };
        list.RemoveRange(1, 2);
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Int_GenericInsert()
    {
        var list = new FixedList32Bytes<int>() { 0, 3, 4 };
        list.Insert(1,1);
        list.Insert(2,2);
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Int_GenericRemoveAt()
    {
        var list = new FixedList32Bytes<int>() { 0, 3, 3, 1, 2 };
        list.RemoveAt(1);
        list.RemoveAt(1);
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Int_GenericRemove()
    {
        var list = new FixedList32Bytes<int>() { 0, 3, 3, 1, 2 };
        Assert.True(list.Remove((int)3));
        Assert.True(list.Remove((int)3));
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Int_GenericRemoveSwapBack()
    {
        var list = new FixedList32Bytes<int>() { 0, 3, 3, 2, 1 };
        Assert.True(list.RemoveSwapBack((int)3));
        Assert.True(list.RemoveSwapBack((int)3));
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Int_GenericSort()
    {
        var list = new FixedList32Bytes<int>();
        for(var i = 0; i < 5; ++i)
          list.Add((int)(4-i));
        list.Sort();
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Int_GenericSortCustomComparer()
    {
        var list = new FixedList32Bytes<int>();
        for(var i = 0; i < 5; ++i)
          list.Add((int)(i));
        list.Sort(new DescendingComparer<int>());
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(4-i, list[i]);
    }

    [Test]
    public unsafe void FixedList32Int_IndexOf()
    {
        var list = new FixedList32Bytes<int>() { 123, 178 };
        bool r0 = false, r1 = false, r2 = false;

        GCAllocRecorder.ValidateNoGCAllocs(() =>
        {
            r0 = -1 != list.IndexOf((int)145);
            r1 = list.Contains((int)123);
            r2 = list.Contains((int)178);
        });

        Assert.False(r0);
        Assert.True(r1);
        Assert.True(r2);
    }


    public readonly unsafe struct FixedList64Int_Wrapper
    {
        readonly FixedList64Bytes<int> _values;
        internal int* Values => (int*)_values.Buffer;
        public FixedList64Int_Wrapper(int x, int y)
        {
            _values = new FixedList64Bytes<int>();
            _values.Add(x);
            _values.Add(y);
            _values.Sort();
        }
    }

    unsafe void FixedList64Int_ReadonlyWorksFunc1(in FixedList64Int_Wrapper list, int* originalValues)
    {
        int* values = list.Values;
        Assert.AreEqual(originalValues[0], values[0], "Values[0] mismatch in func1");
        Assert.AreEqual(originalValues[1], values[1], "Values[1] mismatch in func1");
        Assert.AreEqual((ulong)originalValues, (ulong)values, "Buffer pointer mismatch in func1");
    }

    [Test]
    public unsafe void FixedList64Int_ReadonlyWorks()
    {
        var list = new FixedList64Int_Wrapper(17, 23);
        int* values = list.Values;
        FixedList64Int_ReadonlyWorksFunc1(list, values);
    }

    [Test]
    public void FixedList64Int_FixedBytes64Align8ToNativeArrayWorksGeneric()
    {
        var list = new FixedList<int,FixedBytes64Align8>();

        for(var i = 0; i < 15; ++i)
            list.Add((int)(i * 123 + 234));

        using(var array = list.ToNativeArray(Allocator.Temp))
        {
            for(var i = 0; i < 15; ++i)
                Assert.AreEqual((int)(i * 123 + 234), array[i]);
        }
    }

    [Test]
    public void FixedList64Int_ToNativeArrayWorks()
    {
        var list = new FixedList64Bytes<int>();

        for(var i = 0; i < 15; ++i)
            list.Add((int)(i * 123 + 234));

        using(var array = list.ToNativeArray(Allocator.Temp))
        {
            for(var i = 0; i < 15; ++i)
                Assert.AreEqual((int)(i * 123 + 234), array[i]);
        }
    }

    [Test]
    public void FixedList64Int_GenericHasExpectedLayout()
    {
        var actual = new FixedList64Bytes<int>();
        for(var i = 0; i < 15; ++i)
          actual.Add((int)i);
        unsafe
        {
            var e = stackalloc byte[64];
            e[0] = (byte)((15 >> 0) & 0xFF);
            e[1] = (byte)((15 >> 8) & 0xFF);
            for(var i = 0; i < 15; ++i)
            {
              var s = (int)i;
              UnsafeUtility.MemCpy(e + 2 + FixedList.PaddingBytes<int>() + sizeof(int) * i, &s, sizeof(int));
            }
            Assert.AreEqual(0, UnsafeUtility.MemCmp(e, &actual.data, 64));
        }
    }

    [Test]
    [TestRequiresDotsDebugOrCollectionChecks]
    public void FixedList64Int_GenericHasExpectedCapacity()
    {
        var list = new FixedList64Bytes<int>();
        var expectedCapacity = list.Capacity;
        for(int i = 0; i < expectedCapacity; ++i)
            list.Add((int)i);

        Assert.Throws<IndexOutOfRangeException> (() => { list.Add((int)expectedCapacity); });
    }
    [Test]
    public unsafe void FixedList64Int_GenericAdd()
    {
        var list = new FixedList64Bytes<int>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.Add((int)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.Add(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList64Int_GenericAddRange()
    {
        var list = new FixedList64Bytes<int>();
        var capacity = list.Capacity;
        var items = stackalloc int[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (int)i;

        var half = capacity / 2;
        list.AddRange(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRange(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList64Int_GenericAddNoResize()
    {
        var list = new FixedList64Bytes<int>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.AddNoResize((int)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddNoResize(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList64Int_GenericAddRangeNoResize()
    {
        var list = new FixedList64Bytes<int>();
        var capacity = list.Capacity;
        var items = stackalloc int[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (int)i;

        var half = capacity / 2;
        list.AddRangeNoResize(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRangeNoResize(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList64Int_GenericAddReplicate()
    {
        var list = new FixedList64Bytes<int>();
        list.AddReplicate(42, 2);
        Assert.AreEqual(2, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

        list.AddReplicate(42, 3);
        Assert.AreEqual(5, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddReplicate(42, 1000); });
#endif
        Assert.AreEqual(5, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList64Int_GenericInsertRangeWithBeginEnd()
    {
        var list = new FixedList64Bytes<int>() { 0, 3, 4 };
        list.InsertRangeWithBeginEnd(1,3);
        list[1] = 1;
        list[2] = 2;
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Int_GenericInsertRange()
    {
        var list = new FixedList64Bytes<int>() { 0, 3, 4 };
        Assert.AreEqual(3, list.Length);

        list.InsertRange(1, 2);
        Assert.AreEqual(5, list.Length);
        list[1] = 1;
        list[2] = 2;

        Assert.DoesNotThrow(() => list.InsertRange(1, 0));
        Assert.AreEqual(5, list.Length);

        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Int_GenericRemoveRange()
    {
        var list = new FixedList64Bytes<int>() { 0, 3, 3, 1, 2 };
        list.RemoveRange(1, 2);
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Int_GenericInsert()
    {
        var list = new FixedList64Bytes<int>() { 0, 3, 4 };
        list.Insert(1,1);
        list.Insert(2,2);
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Int_GenericRemoveAt()
    {
        var list = new FixedList64Bytes<int>() { 0, 3, 3, 1, 2 };
        list.RemoveAt(1);
        list.RemoveAt(1);
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Int_GenericRemove()
    {
        var list = new FixedList64Bytes<int>() { 0, 3, 3, 1, 2 };
        Assert.True(list.Remove((int)3));
        Assert.True(list.Remove((int)3));
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Int_GenericRemoveSwapBack()
    {
        var list = new FixedList64Bytes<int>() { 0, 3, 3, 2, 1 };
        Assert.True(list.RemoveSwapBack((int)3));
        Assert.True(list.RemoveSwapBack((int)3));
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Int_GenericSort()
    {
        var list = new FixedList64Bytes<int>();
        for(var i = 0; i < 5; ++i)
          list.Add((int)(4-i));
        list.Sort();
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Int_GenericSortCustomComparer()
    {
        var list = new FixedList64Bytes<int>();
        for(var i = 0; i < 5; ++i)
          list.Add((int)(i));
        list.Sort(new DescendingComparer<int>());
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(4-i, list[i]);
    }

    [Test]
    public unsafe void FixedList64Int_IndexOf()
    {
        var list = new FixedList64Bytes<int>() { 123, 178 };
        bool r0 = false, r1 = false, r2 = false;

        GCAllocRecorder.ValidateNoGCAllocs(() =>
        {
            r0 = -1 != list.IndexOf((int)145);
            r1 = list.Contains((int)123);
            r2 = list.Contains((int)178);
        });

        Assert.False(r0);
        Assert.True(r1);
        Assert.True(r2);
    }


    public readonly unsafe struct FixedList128Int_Wrapper
    {
        readonly FixedList128Bytes<int> _values;
        internal int* Values => (int*)_values.Buffer;
        public FixedList128Int_Wrapper(int x, int y)
        {
            _values = new FixedList128Bytes<int>();
            _values.Add(x);
            _values.Add(y);
            _values.Sort();
        }
    }

    unsafe void FixedList128Int_ReadonlyWorksFunc1(in FixedList128Int_Wrapper list, int* originalValues)
    {
        int* values = list.Values;
        Assert.AreEqual(originalValues[0], values[0], "Values[0] mismatch in func1");
        Assert.AreEqual(originalValues[1], values[1], "Values[1] mismatch in func1");
        Assert.AreEqual((ulong)originalValues, (ulong)values, "Buffer pointer mismatch in func1");
    }

    [Test]
    public unsafe void FixedList128Int_ReadonlyWorks()
    {
        var list = new FixedList128Int_Wrapper(17, 23);
        int* values = list.Values;
        FixedList128Int_ReadonlyWorksFunc1(list, values);
    }

    [Test]
    public void FixedList128Int_FixedBytes128Align8ToNativeArrayWorksGeneric()
    {
        var list = new FixedList<int,FixedBytes128Align8>();

        for(var i = 0; i < 31; ++i)
            list.Add((int)(i * 123 + 234));

        using(var array = list.ToNativeArray(Allocator.Temp))
        {
            for(var i = 0; i < 31; ++i)
                Assert.AreEqual((int)(i * 123 + 234), array[i]);
        }
    }

    [Test]
    public void FixedList128Int_ToNativeArrayWorks()
    {
        var list = new FixedList128Bytes<int>();

        for(var i = 0; i < 31; ++i)
            list.Add((int)(i * 123 + 234));

        using(var array = list.ToNativeArray(Allocator.Temp))
        {
            for(var i = 0; i < 31; ++i)
                Assert.AreEqual((int)(i * 123 + 234), array[i]);
        }
    }

    [Test]
    public void FixedList128Int_GenericHasExpectedLayout()
    {
        var actual = new FixedList128Bytes<int>();
        for(var i = 0; i < 31; ++i)
          actual.Add((int)i);
        unsafe
        {
            var e = stackalloc byte[128];
            e[0] = (byte)((31 >> 0) & 0xFF);
            e[1] = (byte)((31 >> 8) & 0xFF);
            for(var i = 0; i < 31; ++i)
            {
              var s = (int)i;
              UnsafeUtility.MemCpy(e + 2 + FixedList.PaddingBytes<int>() + sizeof(int) * i, &s, sizeof(int));
            }
            Assert.AreEqual(0, UnsafeUtility.MemCmp(e, &actual.data, 128));
        }
    }

    [Test]
    [TestRequiresDotsDebugOrCollectionChecks]
    public void FixedList128Int_GenericHasExpectedCapacity()
    {
        var list = new FixedList128Bytes<int>();
        var expectedCapacity = list.Capacity;
        for(int i = 0; i < expectedCapacity; ++i)
            list.Add((int)i);

        Assert.Throws<IndexOutOfRangeException> (() => { list.Add((int)expectedCapacity); });
    }
    [Test]
    public unsafe void FixedList128Int_GenericAdd()
    {
        var list = new FixedList128Bytes<int>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.Add((int)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.Add(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList128Int_GenericAddRange()
    {
        var list = new FixedList128Bytes<int>();
        var capacity = list.Capacity;
        var items = stackalloc int[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (int)i;

        var half = capacity / 2;
        list.AddRange(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRange(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList128Int_GenericAddNoResize()
    {
        var list = new FixedList128Bytes<int>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.AddNoResize((int)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddNoResize(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList128Int_GenericAddRangeNoResize()
    {
        var list = new FixedList128Bytes<int>();
        var capacity = list.Capacity;
        var items = stackalloc int[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (int)i;

        var half = capacity / 2;
        list.AddRangeNoResize(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRangeNoResize(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList128Int_GenericAddReplicate()
    {
        var list = new FixedList128Bytes<int>();
        list.AddReplicate(42, 2);
        Assert.AreEqual(2, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

        list.AddReplicate(42, 3);
        Assert.AreEqual(5, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddReplicate(42, 1000); });
#endif
        Assert.AreEqual(5, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList128Int_GenericInsertRangeWithBeginEnd()
    {
        var list = new FixedList128Bytes<int>() { 0, 3, 4 };
        list.InsertRangeWithBeginEnd(1,3);
        list[1] = 1;
        list[2] = 2;
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Int_GenericInsertRange()
    {
        var list = new FixedList128Bytes<int>() { 0, 3, 4 };
        Assert.AreEqual(3, list.Length);

        list.InsertRange(1, 2);
        Assert.AreEqual(5, list.Length);
        list[1] = 1;
        list[2] = 2;

        Assert.DoesNotThrow(() => list.InsertRange(1, 0));
        Assert.AreEqual(5, list.Length);

        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Int_GenericRemoveRange()
    {
        var list = new FixedList128Bytes<int>() { 0, 3, 3, 1, 2 };
        list.RemoveRange(1, 2);
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Int_GenericInsert()
    {
        var list = new FixedList128Bytes<int>() { 0, 3, 4 };
        list.Insert(1,1);
        list.Insert(2,2);
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Int_GenericRemoveAt()
    {
        var list = new FixedList128Bytes<int>() { 0, 3, 3, 1, 2 };
        list.RemoveAt(1);
        list.RemoveAt(1);
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Int_GenericRemove()
    {
        var list = new FixedList128Bytes<int>() { 0, 3, 3, 1, 2 };
        Assert.True(list.Remove((int)3));
        Assert.True(list.Remove((int)3));
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Int_GenericRemoveSwapBack()
    {
        var list = new FixedList128Bytes<int>() { 0, 3, 3, 2, 1 };
        Assert.True(list.RemoveSwapBack((int)3));
        Assert.True(list.RemoveSwapBack((int)3));
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Int_GenericSort()
    {
        var list = new FixedList128Bytes<int>();
        for(var i = 0; i < 5; ++i)
          list.Add((int)(4-i));
        list.Sort();
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Int_GenericSortCustomComparer()
    {
        var list = new FixedList128Bytes<int>();
        for(var i = 0; i < 5; ++i)
          list.Add((int)(i));
        list.Sort(new DescendingComparer<int>());
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(4-i, list[i]);
    }

    [Test]
    public unsafe void FixedList128Int_IndexOf()
    {
        var list = new FixedList128Bytes<int>() { 123, 178 };
        bool r0 = false, r1 = false, r2 = false;

        GCAllocRecorder.ValidateNoGCAllocs(() =>
        {
            r0 = -1 != list.IndexOf((int)145);
            r1 = list.Contains((int)123);
            r2 = list.Contains((int)178);
        });

        Assert.False(r0);
        Assert.True(r1);
        Assert.True(r2);
    }


    [Test]
    public void FixedList32Int_HasExpectedLayout()
    {
        var actual = new FixedList32Bytes<int>();
        for(var i = 0; i < 7; ++i)
          actual.Add((int)i);
        unsafe
        {
            var e = stackalloc byte[32];
            e[0] = (byte)((7 >> 0) & 0xFF);
            e[1] = (byte)((7 >> 8) & 0xFF);
            for(var i = 0; i < 7; ++i)
            {
              var s = (int)i;
              UnsafeUtility.MemCpy(e + 2 + FixedList.PaddingBytes<int>() + sizeof(int) * i, &s, sizeof(int));
            }
            Assert.AreEqual(0, UnsafeUtility.MemCmp(e, &actual.data, 32));
        }
    }

    [Test]
    [TestRequiresDotsDebugOrCollectionChecks]
    public void FixedList32Int_HasExpectedCapacity()
    {
        var list = new FixedList32Bytes<int>();
        var expectedCapacity = list.Capacity;
        for(int i = 0; i < expectedCapacity; ++i)
            list.Add((int)i);

        Assert.Throws<IndexOutOfRangeException> (() => { list.Add((int)expectedCapacity); });
    }

#if !UNITY_DOTSRUNTIME        // DOTS-Runtime doesn't support UnityEngine
    class ScriptableObjectFixedList32Int_ : UnityEngine.ScriptableObject
    {
        public FixedList32Bytes<int> List;
    }

    [Test]
    public void FixedList32Int_Serializes()
    {
        var a = UnityEngine.ScriptableObject.CreateInstance<ScriptableObjectFixedList32Int_ >();
        for(int i = 0; i < a.List.Capacity; ++i)
            a.List.Add((int)i);
        var b = UnityEngine.Object.Instantiate(a);
        CollectionAssert.AreEqual(a.List, b.List);
    }
#endif

    [Test]
    public unsafe void FixedList32Int_Add()
    {
        var list = new FixedList32Bytes<int>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.Add((int)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.Add(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList32Int_AddRange()
    {
        var list = new FixedList32Bytes<int>();
        var capacity = list.Capacity;
        var items = stackalloc int[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (int)i;

        var half = capacity / 2;
        list.AddRange(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRange(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList32Int_AddNoResize()
    {
        var list = new FixedList32Bytes<int>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.AddNoResize((int)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddNoResize(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList32Int_AddRangeNoResize()
    {
        var list = new FixedList32Bytes<int>();
        var capacity = list.Capacity;
        var items = stackalloc int[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (int)i;

        var half = capacity / 2;
        list.AddRangeNoResize(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRangeNoResize(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList32Int_AddReplicate()
    {
        var list = new FixedList32Bytes<int>();
        list.AddReplicate(42, 2);
        Assert.AreEqual(2, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

        list.AddReplicate(42, 3);
        Assert.AreEqual(5, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddReplicate(42, 1000); });
#endif
        Assert.AreEqual(5, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList32Int_InsertRangeWithBeginEnd()
    {
        var list = new FixedList32Bytes<int>() { 0, 3, 4 };
        list.InsertRangeWithBeginEnd(1,3);
        list[1] = 1;
        list[2] = 2;
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Int_InsertRange()
    {
        var list = new FixedList32Bytes<int>() { 0, 3, 4 };
        Assert.AreEqual(3, list.Length);

        list.InsertRange(1, 2);
        Assert.AreEqual(5, list.Length);
        list[1] = 1;
        list[2] = 2;

        Assert.DoesNotThrow(() => list.InsertRange(1, 0));
        Assert.AreEqual(5, list.Length);

        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    private static void Expected(ref FixedList32Bytes<int> container, int expectedLength, int[] expected)
    {
        Assert.AreEqual(expectedLength == 0, container.IsEmpty);
        Assert.AreEqual(container.Length, expectedLength);
        for (var i = 0; i < container.Length; ++i)
        {
            Assert.AreEqual(expected[i], container[i]);
        }
    }

    [Test]
    public void FixedList32Int_RemoveAt()
    {
        var list = new FixedList32Bytes<int>() { 0, 3, 3, 1, 2 };
        list.RemoveAt(1);
        list.RemoveAt(1);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList32Int_Remove()
    {
        var list = new FixedList32Bytes<int>() { 0, 3, 3, 1, 2 };
        Assert.True(list.Remove((int)3));
        Assert.True(list.Remove((int)3));
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList32Int_RemoveSwapBack()
    {
        var list = new FixedList32Bytes<int>() { 0, 3, 3, 2, 1 };
        Assert.True(list.RemoveSwapBack((int)3));
        Assert.True(list.RemoveSwapBack((int)3));
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList32Int_RemoveRange()
    {
        var list = new FixedList32Bytes<int>() { 0, 3, 3, 1, 2 };
        list.RemoveRange(1, 2);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList32Int_RemoveAtSwapBack()
    {
        var list = new FixedList32Bytes<int>() { 0, 3, 3, 1, 2 };
        list.RemoveAtSwapBack(1);
        list.RemoveAtSwapBack(1);
        Expected(ref list, 3, new int[] { 0, 1, 3 });
    }

    [Test]
    public void FixedList32Int_RemoveRangeSwapBack()
    {
        var list = new FixedList32Bytes<int>() { 0, 3, 3, 1, 2 };
        list.RemoveRangeSwapBack(1, 2);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList32Int_Insert()
    {
        var list = new FixedList32Bytes<int>() { 0, 3, 4 };
        list.Insert(1,1);
        list.Insert(2,2);
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public unsafe void FixedList32Int_Unaligned_Read_Write()
    {
        int alignment = UnsafeUtility.AlignOf<int>();
        if(alignment == 1)
            return;

        // Create a unaligned FixedList32Bytes<int> and ensure we can still read+write safely
        const int buffSize = 32 * 2;
        byte* buff = stackalloc byte[buffSize];
        UnsafeUtility.MemSet(buff, 0xCD, buffSize);

        int offset = 0;
        while (CollectionHelper.IsAligned((ulong)buff + (ulong)offset, alignment))
            offset++;
        ulong unalignedBuff = (ulong)buff + (ulong)offset;

        var list = (FixedList32Bytes<int>*)(unalignedBuff);
        list->Length = 0;

        for (var i = 0; i < 7; ++i)
            list->Add((int)i);

        for (var i = 0; i < 7; ++i)
            Assert.AreEqual(i, list->ElementAt(i));

        // Ensure we didn't write outside of our fixed list byte range
        for(int i = UnsafeUtility.SizeOf<FixedList32Bytes<int>>() + offset; i < buffSize; ++i)
            Assert.AreEqual(buff[i], 0xCD);
    }

    [Test]
    public void FixedList32Int_Sort()
    {
        var list = new FixedList32Bytes<int>();
        for(var i = 0; i < 5; ++i)
          list.Add((int)(4-i));
        list.Sort();
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Int_To_FixedList64Int()
    {
        var a = new FixedList32Bytes<int>();
        for(var i = 0; i < 7; ++i)
            a.Add((int)i);
        var b = new FixedList64Bytes<int>(a);
        for(var i = 0; i < 7; ++i)
            Assert.AreEqual((int)i, b[i]);
    }
    [Test]
    public void FixedList32Int_To_FixedList128Int()
    {
        var a = new FixedList32Bytes<int>();
        for(var i = 0; i < 7; ++i)
            a.Add((int)i);
        var b = new FixedList128Bytes<int>(a);
        for(var i = 0; i < 7; ++i)
            Assert.AreEqual((int)i, b[i]);
    }

    [Test]
    public void FixedList64Int_HasExpectedLayout()
    {
        var actual = new FixedList64Bytes<int>();
        for(var i = 0; i < 15; ++i)
          actual.Add((int)i);
        unsafe
        {
            var e = stackalloc byte[64];
            e[0] = (byte)((15 >> 0) & 0xFF);
            e[1] = (byte)((15 >> 8) & 0xFF);
            for(var i = 0; i < 15; ++i)
            {
              var s = (int)i;
              UnsafeUtility.MemCpy(e + 2 + FixedList.PaddingBytes<int>() + sizeof(int) * i, &s, sizeof(int));
            }
            Assert.AreEqual(0, UnsafeUtility.MemCmp(e, &actual.data, 64));
        }
    }

    [Test]
    [TestRequiresDotsDebugOrCollectionChecks]
    public void FixedList64Int_HasExpectedCapacity()
    {
        var list = new FixedList64Bytes<int>();
        var expectedCapacity = list.Capacity;
        for(int i = 0; i < expectedCapacity; ++i)
            list.Add((int)i);

        Assert.Throws<IndexOutOfRangeException> (() => { list.Add((int)expectedCapacity); });
    }

#if !UNITY_DOTSRUNTIME        // DOTS-Runtime doesn't support UnityEngine
    class ScriptableObjectFixedList64Int_ : UnityEngine.ScriptableObject
    {
        public FixedList64Bytes<int> List;
    }

    [Test]
    public void FixedList64Int_Serializes()
    {
        var a = UnityEngine.ScriptableObject.CreateInstance<ScriptableObjectFixedList64Int_ >();
        for(int i = 0; i < a.List.Capacity; ++i)
            a.List.Add((int)i);
        var b = UnityEngine.Object.Instantiate(a);
        CollectionAssert.AreEqual(a.List, b.List);
    }
#endif

    [Test]
    public unsafe void FixedList64Int_Add()
    {
        var list = new FixedList64Bytes<int>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.Add((int)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.Add(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList64Int_AddRange()
    {
        var list = new FixedList64Bytes<int>();
        var capacity = list.Capacity;
        var items = stackalloc int[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (int)i;

        var half = capacity / 2;
        list.AddRange(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRange(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList64Int_AddNoResize()
    {
        var list = new FixedList64Bytes<int>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.AddNoResize((int)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddNoResize(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList64Int_AddRangeNoResize()
    {
        var list = new FixedList64Bytes<int>();
        var capacity = list.Capacity;
        var items = stackalloc int[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (int)i;

        var half = capacity / 2;
        list.AddRangeNoResize(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRangeNoResize(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList64Int_AddReplicate()
    {
        var list = new FixedList64Bytes<int>();
        list.AddReplicate(42, 2);
        Assert.AreEqual(2, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

        list.AddReplicate(42, 3);
        Assert.AreEqual(5, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddReplicate(42, 1000); });
#endif
        Assert.AreEqual(5, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList64Int_InsertRangeWithBeginEnd()
    {
        var list = new FixedList64Bytes<int>() { 0, 3, 4 };
        list.InsertRangeWithBeginEnd(1,3);
        list[1] = 1;
        list[2] = 2;
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Int_InsertRange()
    {
        var list = new FixedList64Bytes<int>() { 0, 3, 4 };
        Assert.AreEqual(3, list.Length);

        list.InsertRange(1, 2);
        Assert.AreEqual(5, list.Length);
        list[1] = 1;
        list[2] = 2;

        Assert.DoesNotThrow(() => list.InsertRange(1, 0));
        Assert.AreEqual(5, list.Length);

        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    private static void Expected(ref FixedList64Bytes<int> container, int expectedLength, int[] expected)
    {
        Assert.AreEqual(expectedLength == 0, container.IsEmpty);
        Assert.AreEqual(container.Length, expectedLength);
        for (var i = 0; i < container.Length; ++i)
        {
            Assert.AreEqual(expected[i], container[i]);
        }
    }

    [Test]
    public void FixedList64Int_RemoveAt()
    {
        var list = new FixedList64Bytes<int>() { 0, 3, 3, 1, 2 };
        list.RemoveAt(1);
        list.RemoveAt(1);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList64Int_Remove()
    {
        var list = new FixedList64Bytes<int>() { 0, 3, 3, 1, 2 };
        Assert.True(list.Remove((int)3));
        Assert.True(list.Remove((int)3));
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList64Int_RemoveSwapBack()
    {
        var list = new FixedList64Bytes<int>() { 0, 3, 3, 2, 1 };
        Assert.True(list.RemoveSwapBack((int)3));
        Assert.True(list.RemoveSwapBack((int)3));
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList64Int_RemoveRange()
    {
        var list = new FixedList64Bytes<int>() { 0, 3, 3, 1, 2 };
        list.RemoveRange(1, 2);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList64Int_RemoveAtSwapBack()
    {
        var list = new FixedList64Bytes<int>() { 0, 3, 3, 1, 2 };
        list.RemoveAtSwapBack(1);
        list.RemoveAtSwapBack(1);
        Expected(ref list, 3, new int[] { 0, 1, 3 });
    }

    [Test]
    public void FixedList64Int_RemoveRangeSwapBack()
    {
        var list = new FixedList64Bytes<int>() { 0, 3, 3, 1, 2 };
        list.RemoveRangeSwapBack(1, 2);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList64Int_Insert()
    {
        var list = new FixedList64Bytes<int>() { 0, 3, 4 };
        list.Insert(1,1);
        list.Insert(2,2);
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public unsafe void FixedList64Int_Unaligned_Read_Write()
    {
        int alignment = UnsafeUtility.AlignOf<int>();
        if(alignment == 1)
            return;

        // Create a unaligned FixedList64Bytes<int> and ensure we can still read+write safely
        const int buffSize = 64 * 2;
        byte* buff = stackalloc byte[buffSize];
        UnsafeUtility.MemSet(buff, 0xCD, buffSize);

        int offset = 0;
        while (CollectionHelper.IsAligned((ulong)buff + (ulong)offset, alignment))
            offset++;
        ulong unalignedBuff = (ulong)buff + (ulong)offset;

        var list = (FixedList64Bytes<int>*)(unalignedBuff);
        list->Length = 0;

        for (var i = 0; i < 15; ++i)
            list->Add((int)i);

        for (var i = 0; i < 15; ++i)
            Assert.AreEqual(i, list->ElementAt(i));

        // Ensure we didn't write outside of our fixed list byte range
        for(int i = UnsafeUtility.SizeOf<FixedList64Bytes<int>>() + offset; i < buffSize; ++i)
            Assert.AreEqual(buff[i], 0xCD);
    }

    [Test]
    public void FixedList64Int_Sort()
    {
        var list = new FixedList64Bytes<int>();
        for(var i = 0; i < 5; ++i)
          list.Add((int)(4-i));
        list.Sort();
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Int_To_FixedList32Int()
    {
        var a = new FixedList64Bytes<int>();
        for(var i = 0; i < 15; ++i)
            a.Add((int)i);
#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException> (() => { var b = new FixedList32Bytes<int>(a); } );
#endif
    }
    [Test]
    public void FixedList64Int_To_FixedList128Int()
    {
        var a = new FixedList64Bytes<int>();
        for(var i = 0; i < 15; ++i)
            a.Add((int)i);
        var b = new FixedList128Bytes<int>(a);
        for(var i = 0; i < 15; ++i)
            Assert.AreEqual((int)i, b[i]);
    }

    [Test]
    public void FixedList128Int_HasExpectedLayout()
    {
        var actual = new FixedList128Bytes<int>();
        for(var i = 0; i < 31; ++i)
          actual.Add((int)i);
        unsafe
        {
            var e = stackalloc byte[128];
            e[0] = (byte)((31 >> 0) & 0xFF);
            e[1] = (byte)((31 >> 8) & 0xFF);
            for(var i = 0; i < 31; ++i)
            {
              var s = (int)i;
              UnsafeUtility.MemCpy(e + 2 + FixedList.PaddingBytes<int>() + sizeof(int) * i, &s, sizeof(int));
            }
            Assert.AreEqual(0, UnsafeUtility.MemCmp(e, &actual.data, 128));
        }
    }

    [Test]
    [TestRequiresDotsDebugOrCollectionChecks]
    public void FixedList128Int_HasExpectedCapacity()
    {
        var list = new FixedList128Bytes<int>();
        var expectedCapacity = list.Capacity;
        for(int i = 0; i < expectedCapacity; ++i)
            list.Add((int)i);

        Assert.Throws<IndexOutOfRangeException> (() => { list.Add((int)expectedCapacity); });
    }

#if !UNITY_DOTSRUNTIME        // DOTS-Runtime doesn't support UnityEngine
    class ScriptableObjectFixedList128Int_ : UnityEngine.ScriptableObject
    {
        public FixedList128Bytes<int> List;
    }

    [Test]
    public void FixedList128Int_Serializes()
    {
        var a = UnityEngine.ScriptableObject.CreateInstance<ScriptableObjectFixedList128Int_ >();
        for(int i = 0; i < a.List.Capacity; ++i)
            a.List.Add((int)i);
        var b = UnityEngine.Object.Instantiate(a);
        CollectionAssert.AreEqual(a.List, b.List);
    }
#endif

    [Test]
    public unsafe void FixedList128Int_Add()
    {
        var list = new FixedList128Bytes<int>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.Add((int)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.Add(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList128Int_AddRange()
    {
        var list = new FixedList128Bytes<int>();
        var capacity = list.Capacity;
        var items = stackalloc int[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (int)i;

        var half = capacity / 2;
        list.AddRange(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRange(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList128Int_AddNoResize()
    {
        var list = new FixedList128Bytes<int>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.AddNoResize((int)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddNoResize(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList128Int_AddRangeNoResize()
    {
        var list = new FixedList128Bytes<int>();
        var capacity = list.Capacity;
        var items = stackalloc int[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (int)i;

        var half = capacity / 2;
        list.AddRangeNoResize(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRangeNoResize(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList128Int_AddReplicate()
    {
        var list = new FixedList128Bytes<int>();
        list.AddReplicate(42, 2);
        Assert.AreEqual(2, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

        list.AddReplicate(42, 3);
        Assert.AreEqual(5, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddReplicate(42, 1000); });
#endif
        Assert.AreEqual(5, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList128Int_InsertRangeWithBeginEnd()
    {
        var list = new FixedList128Bytes<int>() { 0, 3, 4 };
        list.InsertRangeWithBeginEnd(1,3);
        list[1] = 1;
        list[2] = 2;
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Int_InsertRange()
    {
        var list = new FixedList128Bytes<int>() { 0, 3, 4 };
        Assert.AreEqual(3, list.Length);

        list.InsertRange(1, 2);
        Assert.AreEqual(5, list.Length);
        list[1] = 1;
        list[2] = 2;

        Assert.DoesNotThrow(() => list.InsertRange(1, 0));
        Assert.AreEqual(5, list.Length);

        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    private static void Expected(ref FixedList128Bytes<int> container, int expectedLength, int[] expected)
    {
        Assert.AreEqual(expectedLength == 0, container.IsEmpty);
        Assert.AreEqual(container.Length, expectedLength);
        for (var i = 0; i < container.Length; ++i)
        {
            Assert.AreEqual(expected[i], container[i]);
        }
    }

    [Test]
    public void FixedList128Int_RemoveAt()
    {
        var list = new FixedList128Bytes<int>() { 0, 3, 3, 1, 2 };
        list.RemoveAt(1);
        list.RemoveAt(1);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList128Int_Remove()
    {
        var list = new FixedList128Bytes<int>() { 0, 3, 3, 1, 2 };
        Assert.True(list.Remove((int)3));
        Assert.True(list.Remove((int)3));
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList128Int_RemoveSwapBack()
    {
        var list = new FixedList128Bytes<int>() { 0, 3, 3, 2, 1 };
        Assert.True(list.RemoveSwapBack((int)3));
        Assert.True(list.RemoveSwapBack((int)3));
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList128Int_RemoveRange()
    {
        var list = new FixedList128Bytes<int>() { 0, 3, 3, 1, 2 };
        list.RemoveRange(1, 2);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList128Int_RemoveAtSwapBack()
    {
        var list = new FixedList128Bytes<int>() { 0, 3, 3, 1, 2 };
        list.RemoveAtSwapBack(1);
        list.RemoveAtSwapBack(1);
        Expected(ref list, 3, new int[] { 0, 1, 3 });
    }

    [Test]
    public void FixedList128Int_RemoveRangeSwapBack()
    {
        var list = new FixedList128Bytes<int>() { 0, 3, 3, 1, 2 };
        list.RemoveRangeSwapBack(1, 2);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList128Int_Insert()
    {
        var list = new FixedList128Bytes<int>() { 0, 3, 4 };
        list.Insert(1,1);
        list.Insert(2,2);
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public unsafe void FixedList128Int_Unaligned_Read_Write()
    {
        int alignment = UnsafeUtility.AlignOf<int>();
        if(alignment == 1)
            return;

        // Create a unaligned FixedList128Bytes<int> and ensure we can still read+write safely
        const int buffSize = 128 * 2;
        byte* buff = stackalloc byte[buffSize];
        UnsafeUtility.MemSet(buff, 0xCD, buffSize);

        int offset = 0;
        while (CollectionHelper.IsAligned((ulong)buff + (ulong)offset, alignment))
            offset++;
        ulong unalignedBuff = (ulong)buff + (ulong)offset;

        var list = (FixedList128Bytes<int>*)(unalignedBuff);
        list->Length = 0;

        for (var i = 0; i < 31; ++i)
            list->Add((int)i);

        for (var i = 0; i < 31; ++i)
            Assert.AreEqual(i, list->ElementAt(i));

        // Ensure we didn't write outside of our fixed list byte range
        for(int i = UnsafeUtility.SizeOf<FixedList128Bytes<int>>() + offset; i < buffSize; ++i)
            Assert.AreEqual(buff[i], 0xCD);
    }

    [Test]
    public void FixedList128Int_Sort()
    {
        var list = new FixedList128Bytes<int>();
        for(var i = 0; i < 5; ++i)
          list.Add((int)(4-i));
        list.Sort();
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Int_To_FixedList32Int()
    {
        var a = new FixedList128Bytes<int>();
        for(var i = 0; i < 31; ++i)
            a.Add((int)i);
#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException> (() => { var b = new FixedList32Bytes<int>(a); } );
#endif
    }
    [Test]
    public void FixedList128Int_To_FixedList64Int()
    {
        var a = new FixedList128Bytes<int>();
        for(var i = 0; i < 31; ++i)
            a.Add((int)i);
#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException> (() => { var b = new FixedList64Bytes<int>(a); } );
#endif
    }

    public readonly unsafe struct FixedList32Float_Wrapper
    {
        readonly FixedList32Bytes<float> _values;
        internal float* Values => (float*)_values.Buffer;
        public FixedList32Float_Wrapper(float x, float y)
        {
            _values = new FixedList32Bytes<float>();
            _values.Add(x);
            _values.Add(y);
            _values.Sort();
        }
    }

    unsafe void FixedList32Float_ReadonlyWorksFunc1(in FixedList32Float_Wrapper list, float* originalValues)
    {
        float* values = list.Values;
        Assert.AreEqual(originalValues[0], values[0], "Values[0] mismatch in func1");
        Assert.AreEqual(originalValues[1], values[1], "Values[1] mismatch in func1");
        Assert.AreEqual((ulong)originalValues, (ulong)values, "Buffer pointer mismatch in func1");
    }

    [Test]
    public unsafe void FixedList32Float_ReadonlyWorks()
    {
        var list = new FixedList32Float_Wrapper(17, 23);
        float* values = list.Values;
        FixedList32Float_ReadonlyWorksFunc1(list, values);
    }

    [Test]
    public void FixedList32Float_FixedBytes32Align8ToNativeArrayWorksGeneric()
    {
        var list = new FixedList<float,FixedBytes32Align8>();

        for(var i = 0; i < 7; ++i)
            list.Add((float)(i * 123 + 234));

        using(var array = list.ToNativeArray(Allocator.Temp))
        {
            for(var i = 0; i < 7; ++i)
                Assert.AreEqual((float)(i * 123 + 234), array[i]);
        }
    }

    [Test]
    public void FixedList32Float_ToNativeArrayWorks()
    {
        var list = new FixedList32Bytes<float>();

        for(var i = 0; i < 7; ++i)
            list.Add((float)(i * 123 + 234));

        using(var array = list.ToNativeArray(Allocator.Temp))
        {
            for(var i = 0; i < 7; ++i)
                Assert.AreEqual((float)(i * 123 + 234), array[i]);
        }
    }

    [Test]
    public void FixedList32Float_GenericHasExpectedLayout()
    {
        var actual = new FixedList32Bytes<float>();
        for(var i = 0; i < 7; ++i)
          actual.Add((float)i);
        unsafe
        {
            var e = stackalloc byte[32];
            e[0] = (byte)((7 >> 0) & 0xFF);
            e[1] = (byte)((7 >> 8) & 0xFF);
            for(var i = 0; i < 7; ++i)
            {
              var s = (float)i;
              UnsafeUtility.MemCpy(e + 2 + FixedList.PaddingBytes<float>() + sizeof(float) * i, &s, sizeof(float));
            }
            Assert.AreEqual(0, UnsafeUtility.MemCmp(e, &actual.data, 32));
        }
    }

    [Test]
    [TestRequiresDotsDebugOrCollectionChecks]
    public void FixedList32Float_GenericHasExpectedCapacity()
    {
        var list = new FixedList32Bytes<float>();
        var expectedCapacity = list.Capacity;
        for(int i = 0; i < expectedCapacity; ++i)
            list.Add((float)i);

        Assert.Throws<IndexOutOfRangeException> (() => { list.Add((float)expectedCapacity); });
    }
    [Test]
    public unsafe void FixedList32Float_GenericAdd()
    {
        var list = new FixedList32Bytes<float>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.Add((float)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.Add(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList32Float_GenericAddRange()
    {
        var list = new FixedList32Bytes<float>();
        var capacity = list.Capacity;
        var items = stackalloc float[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (float)i;

        var half = capacity / 2;
        list.AddRange(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRange(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList32Float_GenericAddNoResize()
    {
        var list = new FixedList32Bytes<float>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.AddNoResize((float)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddNoResize(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList32Float_GenericAddRangeNoResize()
    {
        var list = new FixedList32Bytes<float>();
        var capacity = list.Capacity;
        var items = stackalloc float[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (float)i;

        var half = capacity / 2;
        list.AddRangeNoResize(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRangeNoResize(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList32Float_GenericAddReplicate()
    {
        var list = new FixedList32Bytes<float>();
        list.AddReplicate(42, 2);
        Assert.AreEqual(2, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

        list.AddReplicate(42, 3);
        Assert.AreEqual(5, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddReplicate(42, 1000); });
#endif
        Assert.AreEqual(5, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList32Float_GenericInsertRangeWithBeginEnd()
    {
        var list = new FixedList32Bytes<float>() { 0, 3, 4 };
        list.InsertRangeWithBeginEnd(1,3);
        list[1] = 1;
        list[2] = 2;
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Float_GenericInsertRange()
    {
        var list = new FixedList32Bytes<float>() { 0, 3, 4 };
        Assert.AreEqual(3, list.Length);

        list.InsertRange(1, 2);
        Assert.AreEqual(5, list.Length);
        list[1] = 1;
        list[2] = 2;

        Assert.DoesNotThrow(() => list.InsertRange(1, 0));
        Assert.AreEqual(5, list.Length);

        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Float_GenericRemoveRange()
    {
        var list = new FixedList32Bytes<float>() { 0, 3, 3, 1, 2 };
        list.RemoveRange(1, 2);
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Float_GenericInsert()
    {
        var list = new FixedList32Bytes<float>() { 0, 3, 4 };
        list.Insert(1,1);
        list.Insert(2,2);
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Float_GenericRemoveAt()
    {
        var list = new FixedList32Bytes<float>() { 0, 3, 3, 1, 2 };
        list.RemoveAt(1);
        list.RemoveAt(1);
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Float_GenericRemove()
    {
        var list = new FixedList32Bytes<float>() { 0, 3, 3, 1, 2 };
        Assert.True(list.Remove((float)3));
        Assert.True(list.Remove((float)3));
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Float_GenericRemoveSwapBack()
    {
        var list = new FixedList32Bytes<float>() { 0, 3, 3, 2, 1 };
        Assert.True(list.RemoveSwapBack((float)3));
        Assert.True(list.RemoveSwapBack((float)3));
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Float_GenericSort()
    {
        var list = new FixedList32Bytes<float>();
        for(var i = 0; i < 5; ++i)
          list.Add((float)(4-i));
        list.Sort();
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Float_GenericSortCustomComparer()
    {
        var list = new FixedList32Bytes<float>();
        for(var i = 0; i < 5; ++i)
          list.Add((float)(i));
        list.Sort(new DescendingComparer<float>());
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(4-i, list[i]);
    }

    [Test]
    public unsafe void FixedList32Float_IndexOf()
    {
        var list = new FixedList32Bytes<float>() { 123, 178 };
        bool r0 = false, r1 = false, r2 = false;

        GCAllocRecorder.ValidateNoGCAllocs(() =>
        {
            r0 = -1 != list.IndexOf((float)145);
            r1 = list.Contains((float)123);
            r2 = list.Contains((float)178);
        });

        Assert.False(r0);
        Assert.True(r1);
        Assert.True(r2);
    }


    public readonly unsafe struct FixedList64Float_Wrapper
    {
        readonly FixedList64Bytes<float> _values;
        internal float* Values => (float*)_values.Buffer;
        public FixedList64Float_Wrapper(float x, float y)
        {
            _values = new FixedList64Bytes<float>();
            _values.Add(x);
            _values.Add(y);
            _values.Sort();
        }
    }

    unsafe void FixedList64Float_ReadonlyWorksFunc1(in FixedList64Float_Wrapper list, float* originalValues)
    {
        float* values = list.Values;
        Assert.AreEqual(originalValues[0], values[0], "Values[0] mismatch in func1");
        Assert.AreEqual(originalValues[1], values[1], "Values[1] mismatch in func1");
        Assert.AreEqual((ulong)originalValues, (ulong)values, "Buffer pointer mismatch in func1");
    }

    [Test]
    public unsafe void FixedList64Float_ReadonlyWorks()
    {
        var list = new FixedList64Float_Wrapper(17, 23);
        float* values = list.Values;
        FixedList64Float_ReadonlyWorksFunc1(list, values);
    }

    [Test]
    public void FixedList64Float_FixedBytes64Align8ToNativeArrayWorksGeneric()
    {
        var list = new FixedList<float,FixedBytes64Align8>();

        for(var i = 0; i < 15; ++i)
            list.Add((float)(i * 123 + 234));

        using(var array = list.ToNativeArray(Allocator.Temp))
        {
            for(var i = 0; i < 15; ++i)
                Assert.AreEqual((float)(i * 123 + 234), array[i]);
        }
    }

    [Test]
    public void FixedList64Float_ToNativeArrayWorks()
    {
        var list = new FixedList64Bytes<float>();

        for(var i = 0; i < 15; ++i)
            list.Add((float)(i * 123 + 234));

        using(var array = list.ToNativeArray(Allocator.Temp))
        {
            for(var i = 0; i < 15; ++i)
                Assert.AreEqual((float)(i * 123 + 234), array[i]);
        }
    }

    [Test]
    public void FixedList64Float_GenericHasExpectedLayout()
    {
        var actual = new FixedList64Bytes<float>();
        for(var i = 0; i < 15; ++i)
          actual.Add((float)i);
        unsafe
        {
            var e = stackalloc byte[64];
            e[0] = (byte)((15 >> 0) & 0xFF);
            e[1] = (byte)((15 >> 8) & 0xFF);
            for(var i = 0; i < 15; ++i)
            {
              var s = (float)i;
              UnsafeUtility.MemCpy(e + 2 + FixedList.PaddingBytes<float>() + sizeof(float) * i, &s, sizeof(float));
            }
            Assert.AreEqual(0, UnsafeUtility.MemCmp(e, &actual.data, 64));
        }
    }

    [Test]
    [TestRequiresDotsDebugOrCollectionChecks]
    public void FixedList64Float_GenericHasExpectedCapacity()
    {
        var list = new FixedList64Bytes<float>();
        var expectedCapacity = list.Capacity;
        for(int i = 0; i < expectedCapacity; ++i)
            list.Add((float)i);

        Assert.Throws<IndexOutOfRangeException> (() => { list.Add((float)expectedCapacity); });
    }
    [Test]
    public unsafe void FixedList64Float_GenericAdd()
    {
        var list = new FixedList64Bytes<float>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.Add((float)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.Add(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList64Float_GenericAddRange()
    {
        var list = new FixedList64Bytes<float>();
        var capacity = list.Capacity;
        var items = stackalloc float[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (float)i;

        var half = capacity / 2;
        list.AddRange(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRange(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList64Float_GenericAddNoResize()
    {
        var list = new FixedList64Bytes<float>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.AddNoResize((float)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddNoResize(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList64Float_GenericAddRangeNoResize()
    {
        var list = new FixedList64Bytes<float>();
        var capacity = list.Capacity;
        var items = stackalloc float[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (float)i;

        var half = capacity / 2;
        list.AddRangeNoResize(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRangeNoResize(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList64Float_GenericAddReplicate()
    {
        var list = new FixedList64Bytes<float>();
        list.AddReplicate(42, 2);
        Assert.AreEqual(2, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

        list.AddReplicate(42, 3);
        Assert.AreEqual(5, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddReplicate(42, 1000); });
#endif
        Assert.AreEqual(5, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList64Float_GenericInsertRangeWithBeginEnd()
    {
        var list = new FixedList64Bytes<float>() { 0, 3, 4 };
        list.InsertRangeWithBeginEnd(1,3);
        list[1] = 1;
        list[2] = 2;
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Float_GenericInsertRange()
    {
        var list = new FixedList64Bytes<float>() { 0, 3, 4 };
        Assert.AreEqual(3, list.Length);

        list.InsertRange(1, 2);
        Assert.AreEqual(5, list.Length);
        list[1] = 1;
        list[2] = 2;

        Assert.DoesNotThrow(() => list.InsertRange(1, 0));
        Assert.AreEqual(5, list.Length);

        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Float_GenericRemoveRange()
    {
        var list = new FixedList64Bytes<float>() { 0, 3, 3, 1, 2 };
        list.RemoveRange(1, 2);
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Float_GenericInsert()
    {
        var list = new FixedList64Bytes<float>() { 0, 3, 4 };
        list.Insert(1,1);
        list.Insert(2,2);
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Float_GenericRemoveAt()
    {
        var list = new FixedList64Bytes<float>() { 0, 3, 3, 1, 2 };
        list.RemoveAt(1);
        list.RemoveAt(1);
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Float_GenericRemove()
    {
        var list = new FixedList64Bytes<float>() { 0, 3, 3, 1, 2 };
        Assert.True(list.Remove((float)3));
        Assert.True(list.Remove((float)3));
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Float_GenericRemoveSwapBack()
    {
        var list = new FixedList64Bytes<float>() { 0, 3, 3, 2, 1 };
        Assert.True(list.RemoveSwapBack((float)3));
        Assert.True(list.RemoveSwapBack((float)3));
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Float_GenericSort()
    {
        var list = new FixedList64Bytes<float>();
        for(var i = 0; i < 5; ++i)
          list.Add((float)(4-i));
        list.Sort();
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Float_GenericSortCustomComparer()
    {
        var list = new FixedList64Bytes<float>();
        for(var i = 0; i < 5; ++i)
          list.Add((float)(i));
        list.Sort(new DescendingComparer<float>());
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(4-i, list[i]);
    }

    [Test]
    public unsafe void FixedList64Float_IndexOf()
    {
        var list = new FixedList64Bytes<float>() { 123, 178 };
        bool r0 = false, r1 = false, r2 = false;

        GCAllocRecorder.ValidateNoGCAllocs(() =>
        {
            r0 = -1 != list.IndexOf((float)145);
            r1 = list.Contains((float)123);
            r2 = list.Contains((float)178);
        });

        Assert.False(r0);
        Assert.True(r1);
        Assert.True(r2);
    }


    public readonly unsafe struct FixedList128Float_Wrapper
    {
        readonly FixedList128Bytes<float> _values;
        internal float* Values => (float*)_values.Buffer;
        public FixedList128Float_Wrapper(float x, float y)
        {
            _values = new FixedList128Bytes<float>();
            _values.Add(x);
            _values.Add(y);
            _values.Sort();
        }
    }

    unsafe void FixedList128Float_ReadonlyWorksFunc1(in FixedList128Float_Wrapper list, float* originalValues)
    {
        float* values = list.Values;
        Assert.AreEqual(originalValues[0], values[0], "Values[0] mismatch in func1");
        Assert.AreEqual(originalValues[1], values[1], "Values[1] mismatch in func1");
        Assert.AreEqual((ulong)originalValues, (ulong)values, "Buffer pointer mismatch in func1");
    }

    [Test]
    public unsafe void FixedList128Float_ReadonlyWorks()
    {
        var list = new FixedList128Float_Wrapper(17, 23);
        float* values = list.Values;
        FixedList128Float_ReadonlyWorksFunc1(list, values);
    }

    [Test]
    public void FixedList128Float_FixedBytes128Align8ToNativeArrayWorksGeneric()
    {
        var list = new FixedList<float,FixedBytes128Align8>();

        for(var i = 0; i < 31; ++i)
            list.Add((float)(i * 123 + 234));

        using(var array = list.ToNativeArray(Allocator.Temp))
        {
            for(var i = 0; i < 31; ++i)
                Assert.AreEqual((float)(i * 123 + 234), array[i]);
        }
    }

    [Test]
    public void FixedList128Float_ToNativeArrayWorks()
    {
        var list = new FixedList128Bytes<float>();

        for(var i = 0; i < 31; ++i)
            list.Add((float)(i * 123 + 234));

        using(var array = list.ToNativeArray(Allocator.Temp))
        {
            for(var i = 0; i < 31; ++i)
                Assert.AreEqual((float)(i * 123 + 234), array[i]);
        }
    }

    [Test]
    public void FixedList128Float_GenericHasExpectedLayout()
    {
        var actual = new FixedList128Bytes<float>();
        for(var i = 0; i < 31; ++i)
          actual.Add((float)i);
        unsafe
        {
            var e = stackalloc byte[128];
            e[0] = (byte)((31 >> 0) & 0xFF);
            e[1] = (byte)((31 >> 8) & 0xFF);
            for(var i = 0; i < 31; ++i)
            {
              var s = (float)i;
              UnsafeUtility.MemCpy(e + 2 + FixedList.PaddingBytes<float>() + sizeof(float) * i, &s, sizeof(float));
            }
            Assert.AreEqual(0, UnsafeUtility.MemCmp(e, &actual.data, 128));
        }
    }

    [Test]
    [TestRequiresDotsDebugOrCollectionChecks]
    public void FixedList128Float_GenericHasExpectedCapacity()
    {
        var list = new FixedList128Bytes<float>();
        var expectedCapacity = list.Capacity;
        for(int i = 0; i < expectedCapacity; ++i)
            list.Add((float)i);

        Assert.Throws<IndexOutOfRangeException> (() => { list.Add((float)expectedCapacity); });
    }
    [Test]
    public unsafe void FixedList128Float_GenericAdd()
    {
        var list = new FixedList128Bytes<float>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.Add((float)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.Add(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList128Float_GenericAddRange()
    {
        var list = new FixedList128Bytes<float>();
        var capacity = list.Capacity;
        var items = stackalloc float[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (float)i;

        var half = capacity / 2;
        list.AddRange(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRange(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList128Float_GenericAddNoResize()
    {
        var list = new FixedList128Bytes<float>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.AddNoResize((float)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddNoResize(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList128Float_GenericAddRangeNoResize()
    {
        var list = new FixedList128Bytes<float>();
        var capacity = list.Capacity;
        var items = stackalloc float[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (float)i;

        var half = capacity / 2;
        list.AddRangeNoResize(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRangeNoResize(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList128Float_GenericAddReplicate()
    {
        var list = new FixedList128Bytes<float>();
        list.AddReplicate(42, 2);
        Assert.AreEqual(2, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

        list.AddReplicate(42, 3);
        Assert.AreEqual(5, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddReplicate(42, 1000); });
#endif
        Assert.AreEqual(5, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList128Float_GenericInsertRangeWithBeginEnd()
    {
        var list = new FixedList128Bytes<float>() { 0, 3, 4 };
        list.InsertRangeWithBeginEnd(1,3);
        list[1] = 1;
        list[2] = 2;
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Float_GenericInsertRange()
    {
        var list = new FixedList128Bytes<float>() { 0, 3, 4 };
        Assert.AreEqual(3, list.Length);

        list.InsertRange(1, 2);
        Assert.AreEqual(5, list.Length);
        list[1] = 1;
        list[2] = 2;

        Assert.DoesNotThrow(() => list.InsertRange(1, 0));
        Assert.AreEqual(5, list.Length);

        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Float_GenericRemoveRange()
    {
        var list = new FixedList128Bytes<float>() { 0, 3, 3, 1, 2 };
        list.RemoveRange(1, 2);
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Float_GenericInsert()
    {
        var list = new FixedList128Bytes<float>() { 0, 3, 4 };
        list.Insert(1,1);
        list.Insert(2,2);
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Float_GenericRemoveAt()
    {
        var list = new FixedList128Bytes<float>() { 0, 3, 3, 1, 2 };
        list.RemoveAt(1);
        list.RemoveAt(1);
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Float_GenericRemove()
    {
        var list = new FixedList128Bytes<float>() { 0, 3, 3, 1, 2 };
        Assert.True(list.Remove((float)3));
        Assert.True(list.Remove((float)3));
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Float_GenericRemoveSwapBack()
    {
        var list = new FixedList128Bytes<float>() { 0, 3, 3, 2, 1 };
        Assert.True(list.RemoveSwapBack((float)3));
        Assert.True(list.RemoveSwapBack((float)3));
        for(var i = 0; i < 3; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Float_GenericSort()
    {
        var list = new FixedList128Bytes<float>();
        for(var i = 0; i < 5; ++i)
          list.Add((float)(4-i));
        list.Sort();
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Float_GenericSortCustomComparer()
    {
        var list = new FixedList128Bytes<float>();
        for(var i = 0; i < 5; ++i)
          list.Add((float)(i));
        list.Sort(new DescendingComparer<float>());
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(4-i, list[i]);
    }

    [Test]
    public unsafe void FixedList128Float_IndexOf()
    {
        var list = new FixedList128Bytes<float>() { 123, 178 };
        bool r0 = false, r1 = false, r2 = false;

        GCAllocRecorder.ValidateNoGCAllocs(() =>
        {
            r0 = -1 != list.IndexOf((float)145);
            r1 = list.Contains((float)123);
            r2 = list.Contains((float)178);
        });

        Assert.False(r0);
        Assert.True(r1);
        Assert.True(r2);
    }


    [Test]
    public void FixedList32Float_HasExpectedLayout()
    {
        var actual = new FixedList32Bytes<float>();
        for(var i = 0; i < 7; ++i)
          actual.Add((float)i);
        unsafe
        {
            var e = stackalloc byte[32];
            e[0] = (byte)((7 >> 0) & 0xFF);
            e[1] = (byte)((7 >> 8) & 0xFF);
            for(var i = 0; i < 7; ++i)
            {
              var s = (float)i;
              UnsafeUtility.MemCpy(e + 2 + FixedList.PaddingBytes<float>() + sizeof(float) * i, &s, sizeof(float));
            }
            Assert.AreEqual(0, UnsafeUtility.MemCmp(e, &actual.data, 32));
        }
    }

    [Test]
    [TestRequiresDotsDebugOrCollectionChecks]
    public void FixedList32Float_HasExpectedCapacity()
    {
        var list = new FixedList32Bytes<float>();
        var expectedCapacity = list.Capacity;
        for(int i = 0; i < expectedCapacity; ++i)
            list.Add((float)i);

        Assert.Throws<IndexOutOfRangeException> (() => { list.Add((float)expectedCapacity); });
    }

#if !UNITY_DOTSRUNTIME        // DOTS-Runtime doesn't support UnityEngine
    class ScriptableObjectFixedList32Float_ : UnityEngine.ScriptableObject
    {
        public FixedList32Bytes<float> List;
    }

    [Test]
    public void FixedList32Float_Serializes()
    {
        var a = UnityEngine.ScriptableObject.CreateInstance<ScriptableObjectFixedList32Float_ >();
        for(int i = 0; i < a.List.Capacity; ++i)
            a.List.Add((float)i);
        var b = UnityEngine.Object.Instantiate(a);
        CollectionAssert.AreEqual(a.List, b.List);
    }
#endif

    [Test]
    public unsafe void FixedList32Float_Add()
    {
        var list = new FixedList32Bytes<float>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.Add((float)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.Add(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList32Float_AddRange()
    {
        var list = new FixedList32Bytes<float>();
        var capacity = list.Capacity;
        var items = stackalloc float[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (float)i;

        var half = capacity / 2;
        list.AddRange(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRange(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList32Float_AddNoResize()
    {
        var list = new FixedList32Bytes<float>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.AddNoResize((float)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddNoResize(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList32Float_AddRangeNoResize()
    {
        var list = new FixedList32Bytes<float>();
        var capacity = list.Capacity;
        var items = stackalloc float[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (float)i;

        var half = capacity / 2;
        list.AddRangeNoResize(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRangeNoResize(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList32Float_AddReplicate()
    {
        var list = new FixedList32Bytes<float>();
        list.AddReplicate(42, 2);
        Assert.AreEqual(2, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

        list.AddReplicate(42, 3);
        Assert.AreEqual(5, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddReplicate(42, 1000); });
#endif
        Assert.AreEqual(5, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList32Float_InsertRangeWithBeginEnd()
    {
        var list = new FixedList32Bytes<float>() { 0, 3, 4 };
        list.InsertRangeWithBeginEnd(1,3);
        list[1] = 1;
        list[2] = 2;
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Float_InsertRange()
    {
        var list = new FixedList32Bytes<float>() { 0, 3, 4 };
        Assert.AreEqual(3, list.Length);

        list.InsertRange(1, 2);
        Assert.AreEqual(5, list.Length);
        list[1] = 1;
        list[2] = 2;

        Assert.DoesNotThrow(() => list.InsertRange(1, 0));
        Assert.AreEqual(5, list.Length);

        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    private static void Expected(ref FixedList32Bytes<float> container, int expectedLength, int[] expected)
    {
        Assert.AreEqual(expectedLength == 0, container.IsEmpty);
        Assert.AreEqual(container.Length, expectedLength);
        for (var i = 0; i < container.Length; ++i)
        {
            Assert.AreEqual(expected[i], container[i]);
        }
    }

    [Test]
    public void FixedList32Float_RemoveAt()
    {
        var list = new FixedList32Bytes<float>() { 0, 3, 3, 1, 2 };
        list.RemoveAt(1);
        list.RemoveAt(1);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList32Float_Remove()
    {
        var list = new FixedList32Bytes<float>() { 0, 3, 3, 1, 2 };
        Assert.True(list.Remove((float)3));
        Assert.True(list.Remove((float)3));
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList32Float_RemoveSwapBack()
    {
        var list = new FixedList32Bytes<float>() { 0, 3, 3, 2, 1 };
        Assert.True(list.RemoveSwapBack((float)3));
        Assert.True(list.RemoveSwapBack((float)3));
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList32Float_RemoveRange()
    {
        var list = new FixedList32Bytes<float>() { 0, 3, 3, 1, 2 };
        list.RemoveRange(1, 2);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList32Float_RemoveAtSwapBack()
    {
        var list = new FixedList32Bytes<float>() { 0, 3, 3, 1, 2 };
        list.RemoveAtSwapBack(1);
        list.RemoveAtSwapBack(1);
        Expected(ref list, 3, new int[] { 0, 1, 3 });
    }

    [Test]
    public void FixedList32Float_RemoveRangeSwapBack()
    {
        var list = new FixedList32Bytes<float>() { 0, 3, 3, 1, 2 };
        list.RemoveRangeSwapBack(1, 2);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList32Float_Insert()
    {
        var list = new FixedList32Bytes<float>() { 0, 3, 4 };
        list.Insert(1,1);
        list.Insert(2,2);
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public unsafe void FixedList32Float_Unaligned_Read_Write()
    {
        int alignment = UnsafeUtility.AlignOf<float>();
        if(alignment == 1)
            return;

        // Create a unaligned FixedList32Bytes<float> and ensure we can still read+write safely
        const int buffSize = 32 * 2;
        byte* buff = stackalloc byte[buffSize];
        UnsafeUtility.MemSet(buff, 0xCD, buffSize);

        int offset = 0;
        while (CollectionHelper.IsAligned((ulong)buff + (ulong)offset, alignment))
            offset++;
        ulong unalignedBuff = (ulong)buff + (ulong)offset;

        var list = (FixedList32Bytes<float>*)(unalignedBuff);
        list->Length = 0;

        for (var i = 0; i < 7; ++i)
            list->Add((float)i);

        for (var i = 0; i < 7; ++i)
            Assert.AreEqual(i, list->ElementAt(i));

        // Ensure we didn't write outside of our fixed list byte range
        for(int i = UnsafeUtility.SizeOf<FixedList32Bytes<float>>() + offset; i < buffSize; ++i)
            Assert.AreEqual(buff[i], 0xCD);
    }

    [Test]
    public void FixedList32Float_Sort()
    {
        var list = new FixedList32Bytes<float>();
        for(var i = 0; i < 5; ++i)
          list.Add((float)(4-i));
        list.Sort();
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList32Float_To_FixedList64Float()
    {
        var a = new FixedList32Bytes<float>();
        for(var i = 0; i < 7; ++i)
            a.Add((float)i);
        var b = new FixedList64Bytes<float>(a);
        for(var i = 0; i < 7; ++i)
            Assert.AreEqual((float)i, b[i]);
    }
    [Test]
    public void FixedList32Float_To_FixedList128Float()
    {
        var a = new FixedList32Bytes<float>();
        for(var i = 0; i < 7; ++i)
            a.Add((float)i);
        var b = new FixedList128Bytes<float>(a);
        for(var i = 0; i < 7; ++i)
            Assert.AreEqual((float)i, b[i]);
    }

    [Test]
    public void FixedList64Float_HasExpectedLayout()
    {
        var actual = new FixedList64Bytes<float>();
        for(var i = 0; i < 15; ++i)
          actual.Add((float)i);
        unsafe
        {
            var e = stackalloc byte[64];
            e[0] = (byte)((15 >> 0) & 0xFF);
            e[1] = (byte)((15 >> 8) & 0xFF);
            for(var i = 0; i < 15; ++i)
            {
              var s = (float)i;
              UnsafeUtility.MemCpy(e + 2 + FixedList.PaddingBytes<float>() + sizeof(float) * i, &s, sizeof(float));
            }
            Assert.AreEqual(0, UnsafeUtility.MemCmp(e, &actual.data, 64));
        }
    }

    [Test]
    [TestRequiresDotsDebugOrCollectionChecks]
    public void FixedList64Float_HasExpectedCapacity()
    {
        var list = new FixedList64Bytes<float>();
        var expectedCapacity = list.Capacity;
        for(int i = 0; i < expectedCapacity; ++i)
            list.Add((float)i);

        Assert.Throws<IndexOutOfRangeException> (() => { list.Add((float)expectedCapacity); });
    }

#if !UNITY_DOTSRUNTIME        // DOTS-Runtime doesn't support UnityEngine
    class ScriptableObjectFixedList64Float_ : UnityEngine.ScriptableObject
    {
        public FixedList64Bytes<float> List;
    }

    [Test]
    public void FixedList64Float_Serializes()
    {
        var a = UnityEngine.ScriptableObject.CreateInstance<ScriptableObjectFixedList64Float_ >();
        for(int i = 0; i < a.List.Capacity; ++i)
            a.List.Add((float)i);
        var b = UnityEngine.Object.Instantiate(a);
        CollectionAssert.AreEqual(a.List, b.List);
    }
#endif

    [Test]
    public unsafe void FixedList64Float_Add()
    {
        var list = new FixedList64Bytes<float>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.Add((float)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.Add(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList64Float_AddRange()
    {
        var list = new FixedList64Bytes<float>();
        var capacity = list.Capacity;
        var items = stackalloc float[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (float)i;

        var half = capacity / 2;
        list.AddRange(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRange(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList64Float_AddNoResize()
    {
        var list = new FixedList64Bytes<float>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.AddNoResize((float)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddNoResize(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList64Float_AddRangeNoResize()
    {
        var list = new FixedList64Bytes<float>();
        var capacity = list.Capacity;
        var items = stackalloc float[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (float)i;

        var half = capacity / 2;
        list.AddRangeNoResize(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRangeNoResize(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList64Float_AddReplicate()
    {
        var list = new FixedList64Bytes<float>();
        list.AddReplicate(42, 2);
        Assert.AreEqual(2, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

        list.AddReplicate(42, 3);
        Assert.AreEqual(5, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddReplicate(42, 1000); });
#endif
        Assert.AreEqual(5, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList64Float_InsertRangeWithBeginEnd()
    {
        var list = new FixedList64Bytes<float>() { 0, 3, 4 };
        list.InsertRangeWithBeginEnd(1,3);
        list[1] = 1;
        list[2] = 2;
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Float_InsertRange()
    {
        var list = new FixedList64Bytes<float>() { 0, 3, 4 };
        Assert.AreEqual(3, list.Length);

        list.InsertRange(1, 2);
        Assert.AreEqual(5, list.Length);
        list[1] = 1;
        list[2] = 2;

        Assert.DoesNotThrow(() => list.InsertRange(1, 0));
        Assert.AreEqual(5, list.Length);

        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    private static void Expected(ref FixedList64Bytes<float> container, int expectedLength, int[] expected)
    {
        Assert.AreEqual(expectedLength == 0, container.IsEmpty);
        Assert.AreEqual(container.Length, expectedLength);
        for (var i = 0; i < container.Length; ++i)
        {
            Assert.AreEqual(expected[i], container[i]);
        }
    }

    [Test]
    public void FixedList64Float_RemoveAt()
    {
        var list = new FixedList64Bytes<float>() { 0, 3, 3, 1, 2 };
        list.RemoveAt(1);
        list.RemoveAt(1);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList64Float_Remove()
    {
        var list = new FixedList64Bytes<float>() { 0, 3, 3, 1, 2 };
        Assert.True(list.Remove((float)3));
        Assert.True(list.Remove((float)3));
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList64Float_RemoveSwapBack()
    {
        var list = new FixedList64Bytes<float>() { 0, 3, 3, 2, 1 };
        Assert.True(list.RemoveSwapBack((float)3));
        Assert.True(list.RemoveSwapBack((float)3));
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList64Float_RemoveRange()
    {
        var list = new FixedList64Bytes<float>() { 0, 3, 3, 1, 2 };
        list.RemoveRange(1, 2);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList64Float_RemoveAtSwapBack()
    {
        var list = new FixedList64Bytes<float>() { 0, 3, 3, 1, 2 };
        list.RemoveAtSwapBack(1);
        list.RemoveAtSwapBack(1);
        Expected(ref list, 3, new int[] { 0, 1, 3 });
    }

    [Test]
    public void FixedList64Float_RemoveRangeSwapBack()
    {
        var list = new FixedList64Bytes<float>() { 0, 3, 3, 1, 2 };
        list.RemoveRangeSwapBack(1, 2);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList64Float_Insert()
    {
        var list = new FixedList64Bytes<float>() { 0, 3, 4 };
        list.Insert(1,1);
        list.Insert(2,2);
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public unsafe void FixedList64Float_Unaligned_Read_Write()
    {
        int alignment = UnsafeUtility.AlignOf<float>();
        if(alignment == 1)
            return;

        // Create a unaligned FixedList64Bytes<float> and ensure we can still read+write safely
        const int buffSize = 64 * 2;
        byte* buff = stackalloc byte[buffSize];
        UnsafeUtility.MemSet(buff, 0xCD, buffSize);

        int offset = 0;
        while (CollectionHelper.IsAligned((ulong)buff + (ulong)offset, alignment))
            offset++;
        ulong unalignedBuff = (ulong)buff + (ulong)offset;

        var list = (FixedList64Bytes<float>*)(unalignedBuff);
        list->Length = 0;

        for (var i = 0; i < 15; ++i)
            list->Add((float)i);

        for (var i = 0; i < 15; ++i)
            Assert.AreEqual(i, list->ElementAt(i));

        // Ensure we didn't write outside of our fixed list byte range
        for(int i = UnsafeUtility.SizeOf<FixedList64Bytes<float>>() + offset; i < buffSize; ++i)
            Assert.AreEqual(buff[i], 0xCD);
    }

    [Test]
    public void FixedList64Float_Sort()
    {
        var list = new FixedList64Bytes<float>();
        for(var i = 0; i < 5; ++i)
          list.Add((float)(4-i));
        list.Sort();
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList64Float_To_FixedList32Float()
    {
        var a = new FixedList64Bytes<float>();
        for(var i = 0; i < 15; ++i)
            a.Add((float)i);
#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException> (() => { var b = new FixedList32Bytes<float>(a); } );
#endif
    }
    [Test]
    public void FixedList64Float_To_FixedList128Float()
    {
        var a = new FixedList64Bytes<float>();
        for(var i = 0; i < 15; ++i)
            a.Add((float)i);
        var b = new FixedList128Bytes<float>(a);
        for(var i = 0; i < 15; ++i)
            Assert.AreEqual((float)i, b[i]);
    }

    [Test]
    public void FixedList128Float_HasExpectedLayout()
    {
        var actual = new FixedList128Bytes<float>();
        for(var i = 0; i < 31; ++i)
          actual.Add((float)i);
        unsafe
        {
            var e = stackalloc byte[128];
            e[0] = (byte)((31 >> 0) & 0xFF);
            e[1] = (byte)((31 >> 8) & 0xFF);
            for(var i = 0; i < 31; ++i)
            {
              var s = (float)i;
              UnsafeUtility.MemCpy(e + 2 + FixedList.PaddingBytes<float>() + sizeof(float) * i, &s, sizeof(float));
            }
            Assert.AreEqual(0, UnsafeUtility.MemCmp(e, &actual.data, 128));
        }
    }

    [Test]
    [TestRequiresDotsDebugOrCollectionChecks]
    public void FixedList128Float_HasExpectedCapacity()
    {
        var list = new FixedList128Bytes<float>();
        var expectedCapacity = list.Capacity;
        for(int i = 0; i < expectedCapacity; ++i)
            list.Add((float)i);

        Assert.Throws<IndexOutOfRangeException> (() => { list.Add((float)expectedCapacity); });
    }

#if !UNITY_DOTSRUNTIME        // DOTS-Runtime doesn't support UnityEngine
    class ScriptableObjectFixedList128Float_ : UnityEngine.ScriptableObject
    {
        public FixedList128Bytes<float> List;
    }

    [Test]
    public void FixedList128Float_Serializes()
    {
        var a = UnityEngine.ScriptableObject.CreateInstance<ScriptableObjectFixedList128Float_ >();
        for(int i = 0; i < a.List.Capacity; ++i)
            a.List.Add((float)i);
        var b = UnityEngine.Object.Instantiate(a);
        CollectionAssert.AreEqual(a.List, b.List);
    }
#endif

    [Test]
    public unsafe void FixedList128Float_Add()
    {
        var list = new FixedList128Bytes<float>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.Add((float)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.Add(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList128Float_AddRange()
    {
        var list = new FixedList128Bytes<float>();
        var capacity = list.Capacity;
        var items = stackalloc float[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (float)i;

        var half = capacity / 2;
        list.AddRange(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRange(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList128Float_AddNoResize()
    {
        var list = new FixedList128Bytes<float>();
        var capacity = list.Capacity;
        for (var i = 0; i < capacity; ++i)
        {
            list.AddNoResize((float)i);
            Assert.AreEqual(i + 1, list.Length);
            Assert.AreEqual(i, list[i]);
        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddNoResize(0); });
#endif
        Assert.AreEqual(capacity, list.Length); // Verify length didn't change
    }

    [Test]
    public unsafe void FixedList128Float_AddRangeNoResize()
    {
        var list = new FixedList128Bytes<float>();
        var capacity = list.Capacity;
        var items = stackalloc float[capacity];
        for (var i = 0; i < capacity; ++i)
            items[i] = (float)i;

        var half = capacity / 2;
        list.AddRangeNoResize(items, half);
        Assert.AreEqual(half, list.Length);
        for (var i = 0; i < half; ++i)
            Assert.AreEqual(i, list[i]);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddRangeNoResize(items, capacity); });
#endif
        Assert.AreEqual(half, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList128Float_AddReplicate()
    {
        var list = new FixedList128Bytes<float>();
        list.AddReplicate(42, 2);
        Assert.AreEqual(2, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

        list.AddReplicate(42, 3);
        Assert.AreEqual(5, list.Length);
        foreach (var item in list)
            Assert.AreEqual(42, item);

#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException>(() => { list.AddReplicate(42, 1000); });
#endif
        Assert.AreEqual(5, list.Length); // Verify length didn't change
    }

    [Test]
    public void FixedList128Float_InsertRangeWithBeginEnd()
    {
        var list = new FixedList128Bytes<float>() { 0, 3, 4 };
        list.InsertRangeWithBeginEnd(1,3);
        list[1] = 1;
        list[2] = 2;
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Float_InsertRange()
    {
        var list = new FixedList128Bytes<float>() { 0, 3, 4 };
        Assert.AreEqual(3, list.Length);

        list.InsertRange(1, 2);
        Assert.AreEqual(5, list.Length);
        list[1] = 1;
        list[2] = 2;

        Assert.DoesNotThrow(() => list.InsertRange(1, 0));
        Assert.AreEqual(5, list.Length);

        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    private static void Expected(ref FixedList128Bytes<float> container, int expectedLength, int[] expected)
    {
        Assert.AreEqual(expectedLength == 0, container.IsEmpty);
        Assert.AreEqual(container.Length, expectedLength);
        for (var i = 0; i < container.Length; ++i)
        {
            Assert.AreEqual(expected[i], container[i]);
        }
    }

    [Test]
    public void FixedList128Float_RemoveAt()
    {
        var list = new FixedList128Bytes<float>() { 0, 3, 3, 1, 2 };
        list.RemoveAt(1);
        list.RemoveAt(1);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList128Float_Remove()
    {
        var list = new FixedList128Bytes<float>() { 0, 3, 3, 1, 2 };
        Assert.True(list.Remove((float)3));
        Assert.True(list.Remove((float)3));
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList128Float_RemoveSwapBack()
    {
        var list = new FixedList128Bytes<float>() { 0, 3, 3, 2, 1 };
        Assert.True(list.RemoveSwapBack((float)3));
        Assert.True(list.RemoveSwapBack((float)3));
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList128Float_RemoveRange()
    {
        var list = new FixedList128Bytes<float>() { 0, 3, 3, 1, 2 };
        list.RemoveRange(1, 2);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList128Float_RemoveAtSwapBack()
    {
        var list = new FixedList128Bytes<float>() { 0, 3, 3, 1, 2 };
        list.RemoveAtSwapBack(1);
        list.RemoveAtSwapBack(1);
        Expected(ref list, 3, new int[] { 0, 1, 3 });
    }

    [Test]
    public void FixedList128Float_RemoveRangeSwapBack()
    {
        var list = new FixedList128Bytes<float>() { 0, 3, 3, 1, 2 };
        list.RemoveRangeSwapBack(1, 2);
        Expected(ref list, 3, new int[] { 0, 1, 2 });
    }

    [Test]
    public void FixedList128Float_Insert()
    {
        var list = new FixedList128Bytes<float>() { 0, 3, 4 };
        list.Insert(1,1);
        list.Insert(2,2);
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public unsafe void FixedList128Float_Unaligned_Read_Write()
    {
        int alignment = UnsafeUtility.AlignOf<float>();
        if(alignment == 1)
            return;

        // Create a unaligned FixedList128Bytes<float> and ensure we can still read+write safely
        const int buffSize = 128 * 2;
        byte* buff = stackalloc byte[buffSize];
        UnsafeUtility.MemSet(buff, 0xCD, buffSize);

        int offset = 0;
        while (CollectionHelper.IsAligned((ulong)buff + (ulong)offset, alignment))
            offset++;
        ulong unalignedBuff = (ulong)buff + (ulong)offset;

        var list = (FixedList128Bytes<float>*)(unalignedBuff);
        list->Length = 0;

        for (var i = 0; i < 31; ++i)
            list->Add((float)i);

        for (var i = 0; i < 31; ++i)
            Assert.AreEqual(i, list->ElementAt(i));

        // Ensure we didn't write outside of our fixed list byte range
        for(int i = UnsafeUtility.SizeOf<FixedList128Bytes<float>>() + offset; i < buffSize; ++i)
            Assert.AreEqual(buff[i], 0xCD);
    }

    [Test]
    public void FixedList128Float_Sort()
    {
        var list = new FixedList128Bytes<float>();
        for(var i = 0; i < 5; ++i)
          list.Add((float)(4-i));
        list.Sort();
        for(var i = 0; i < 5; ++i)
            Assert.AreEqual(i, list[i]);
    }

    [Test]
    public void FixedList128Float_To_FixedList32Float()
    {
        var a = new FixedList128Bytes<float>();
        for(var i = 0; i < 31; ++i)
            a.Add((float)i);
#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException> (() => { var b = new FixedList32Bytes<float>(a); } );
#endif
    }
    [Test]
    public void FixedList128Float_To_FixedList64Float()
    {
        var a = new FixedList128Bytes<float>();
        for(var i = 0; i < 31; ++i)
            a.Add((float)i);
#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
        Assert.Throws<IndexOutOfRangeException> (() => { var b = new FixedList64Bytes<float>(a); } );
#endif
    }

}
