/// <summary>
/// Determines whether two spans are structurally (byte-wise) equal by comparing the elements by using memcmp
/// </summary>
/// <param name="first">A span, of type T to compare to second.</param>
/// <param name="second">A span, of type U to compare to first.</param>
public static bool BlockEquals <[Primitive] T, [Primitive] U>(this ReadOnlySpan <T> first, ReadOnlySpan <U> second)
where T : struct
where U : struct
{
var bytesCount = (ulong)first.Length * (ulong)Unsafe.SizeOf <T>();
if (bytesCount != (ulong)second.Length * (ulong)Unsafe.SizeOf <U>())
{
return(false);
}
// perf: it is cheaper to compare 'n' long elements than 'n*8' bytes (in a loop)
if ((bytesCount & 0x00000007) == 0) // fast % sizeof(long)
{
return(SequenceEqual(first.NonPortableCast <T, long>(), second.NonPortableCast <U, long>()));
}
if ((bytesCount & 0x00000003) == 0) // fast % sizeof(int)
{
return(SequenceEqual(first.NonPortableCast <T, int>(), second.NonPortableCast <U, int>()));
}
if ((bytesCount & 0x00000001) == 0) // fast % sizeof(short)
{
return(SequenceEqual(first.NonPortableCast <T, short>(), second.NonPortableCast <U, short>()));
}
return(SpanExtensions.SequenceEqual(first.NonPortableCast <T, byte>(), second.NonPortableCast <U, byte>()));
}