public void SliceTests()
        {
            // Span from normal array
            byte[] array = new byte[16] {
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
            };
            SpanByte span = new SpanByte(array);
            // Slice 2 elements and check
            var sliced = span.Slice(0, 2);

            Assert.Equal(sliced.Length, 2, "Sliced span lenght must be 2");
            Assert.Equal(sliced[0], (byte)0x00, "Sliced first element must be value 0");
            Assert.Equal(sliced[1], (byte)0x01, "Sliced first element must be value 1");

            // Slide 4 elements starting at index 2 and check
            sliced = span.Slice(2, 4);
            Assert.Equal(sliced.Length, 4, "Sliced span lenght must be 4");
            Assert.Equal(sliced[0], (byte)0x02, "Sliced first element must be value 2");
            Assert.Equal(sliced[1], (byte)0x03, "Sliced first element must be value 3");
            Assert.Equal(sliced[2], (byte)0x04, "Sliced first element must be value 4");
            Assert.Equal(sliced[3], (byte)0x05, "Sliced first element must be value 5");

            // Slide starting 4 at element check
            sliced = span.Slice(4);
            Assert.Equal(sliced.Length, 12, "Sliced span lenght must be 12");
            for (int i = 0; i < sliced.Length; i++)
            {
                Assert.Equal(sliced[i], span[i + 4], "SpanByte value should be the same as from the original span");
            }

            // Slice of slice
            var secondSliced = sliced.Slice(2, 4);

            Assert.Equal(secondSliced.Length, 4, "Sliced span lenght must be 12");
            for (int i = 0; i < secondSliced.Length; i++)
            {
                Assert.Equal(secondSliced[i], sliced[i + 2], "SpanByte value should be the same as from the original span");
            }

            // Should be an empty one
            var empty = span.Slice(span.Length);

            Assert.Equal(empty.Length, 0, "slicing all the span should result in an empty span");
            Assert.True(empty.IsEmpty, "Empty span should be empty");
        }
        public void RaisingExceptionsOfAllKindsTests()
        {
            // Should raise an exception on creation
            Assert.Throws(typeof(ArgumentOutOfRangeException), () => { SpanByte span = new SpanByte(null, 1, 2); }, "ArgumentOutOfRangeException when array is null, start is 1 and length is 2");
            Assert.Throws(typeof(ArgumentOutOfRangeException), () => { SpanByte span = new SpanByte(new byte[1], 1, 2); }, "ArgumentOutOfRangeException when array is new byte[1], start is 1 and length is 2");
            Assert.Throws(typeof(ArgumentOutOfRangeException), () => { SpanByte span = new SpanByte(new byte[1], 0, 2); }, "ArgumentOutOfRangeException when array is new byte[1], start is 0 and length is 2");
            Assert.Throws(typeof(ArgumentOutOfRangeException), () => { SpanByte span = new SpanByte(new byte[1], 2, 0); }, "ArgumentOutOfRangeException when array is new byte[1], start is 2 and length is 0");

            // Exception on index access
            byte[] array = new byte[16] {
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
            };
            Assert.Throws(typeof(ArgumentOutOfRangeException), () =>
            {
                SpanByte span = new SpanByte(array);
                var data      = span[span.Length];
            });
            Assert.Throws(typeof(IndexOutOfRangeException), () =>
            {
                SpanByte span = new SpanByte(array);
                var data      = span[-1];
            });

            // Copy to with too small destination
            Assert.Throws(typeof(ArgumentException), () =>
            {
                SpanByte span        = new SpanByte(array);
                SpanByte destination = new byte[span.Length - 1];
                span.CopyTo(destination);
            });

            // Slicing arguments
            Assert.Throws(typeof(ArgumentOutOfRangeException), () =>
            {
                SpanByte span = new SpanByte(array);
                var sliced    = span.Slice(span.Length + 1);
            });
            Assert.Throws(typeof(ArgumentOutOfRangeException), () =>
            {
                SpanByte span = new SpanByte(array);
                var sliced    = span.Slice(1, span.Length);
            });

            Assert.Throws(typeof(ArgumentOutOfRangeException), () =>
            {
                SpanByte span = new SpanByte(array);
                var sliced    = span.Slice(-1, span.Length);
            });

            Assert.Throws(typeof(ArgumentOutOfRangeException), () =>
            {
                SpanByte span = new SpanByte(array);
                var sliced    = span.Slice(1, -1);
            });
        }