where T : IEquatable<T>
{
int length = first.Length;
- if (typeof(T) == typeof(byte))
+ if (typeof(T) == typeof(byte) || typeof(T) == typeof(sbyte))
return length == second.Length &&
SpanHelpers.SequenceEqual(
ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(first)),
ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(second)),
length);
+
+ if (typeof(T) == typeof(char) || typeof(T) == typeof(short) || typeof(T) == typeof(ushort))
+ return length == second.Length &&
+ SpanHelpers.SequenceEqualBytes(
+ ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(first)),
+ ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(second)),
+ ((nuint)length) * 2); // If this multiplication overflows, the Span we got overflows the entire address range. There's no happy outcome for this api in such a case so we choose not to take the overhead of checking.
+
+ if (typeof(T) == typeof(int) || typeof(T) == typeof(uint))
+ return length == second.Length &&
+ SpanHelpers.SequenceEqualBytes(
+ ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(first)),
+ ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(second)),
+ ((nuint)length) * 4); // If this multiplication overflows, the Span we got overflows the entire address range. There's no happy outcome for this api in such a case so we choose not to take the overhead of checking.
+
+ if (typeof(T) == typeof(long) || typeof(T) == typeof(ulong))
+ return length == second.Length &&
+ SpanHelpers.SequenceEqualBytes(
+ ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(first)),
+ ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(second)),
+ ((nuint)length) * 8); // If this multiplication overflows, the Span we got overflows the entire address range. There's no happy outcome for this api in such a case so we choose not to take the overhead of checking.
+
return length == second.Length && SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(first), ref MemoryMarshal.GetReference(second), length);
}