DotNext by Roman Sakno

<PackageReference Include="DotNext" Version="1.0.1" />

 BitwiseComparer<T>

public sealed class BitwiseComparer<T> : IEqualityComparer<T>, IComparer<T> where T : struct
Represents bitwise comparer for the arbitrary value type.
using DotNext.Runtime.InteropServices; using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace DotNext { public sealed class BitwiseComparer<T> : IEqualityComparer<T>, IComparer<T> where T : struct { public BitwiseComparer<T> Instance { get; } = new BitwiseComparer<T>(); private BitwiseComparer() { } private unsafe static bool Equals<G>(ref T first, ref G second) where G : struct { long num = sizeof(T); int num2 = (num == sizeof(G)) ? 1 : 0; if (num2 != 0) { long num3 = num - 1; if ((ulong)num3 <= 3) { switch (num3) { case 2: goto IL_003d; case 0: goto IL_0047; case 1: goto IL_004f; case 3: goto IL_0057; } } if (num != 8) goto IL_003d; num2 = ((*(long*)(&first) == *(long*)(&second)) ? 1 : 0); } goto IL_0065; IL_003d: num2 = (Memory.EqualsAligned((IntPtr)(&first), (IntPtr)(&second), num) ? 1 : 0); goto IL_0065; IL_0047: num2 = ((*(byte*)(&first) == *(sbyte*)(&second)) ? 1 : 0); goto IL_0065; IL_004f: num2 = ((*(short*)(&first) == *(short*)(&second)) ? 1 : 0); goto IL_0065; IL_0065: return (byte)num2 != 0; IL_0057: num2 = ((*(int*)(&first) == *(int*)(&second)) ? 1 : 0); goto IL_0065; } public static bool Equals<G>(T first, G second) where G : struct { return Equals(ref first, ref second); } private unsafe static int Compare<G>(ref T first, ref G second) where G : struct { long num = sizeof(T); int num2 = (num == sizeof(G)) ? 1 : 0; if (num2 != 0) { long num3 = num - 1; if ((ulong)num3 <= 3) { switch (num3) { case 2: goto IL_003d; case 0: goto IL_0047; case 1: goto IL_0051; case 3: goto IL_005b; } } if (num != 8) goto IL_003d; num2 = ((ulong)first).CompareTo(*(ulong*)(&second)); } goto IL_0071; IL_003d: num2 = Memory.CompareUnaligned((IntPtr)(&first), (IntPtr)(&second), num); goto IL_0071; IL_0047: num2 = ((byte)first).CompareTo(*(byte*)(&second)); goto IL_0071; IL_0051: num2 = ((ushort)first).CompareTo(*(ushort*)(&second)); goto IL_0071; IL_0071: return num2; IL_005b: num2 = ((uint)first).CompareTo(*(uint*)(&second)); goto IL_0071; } public static int Compare<G>(T first, G second) where G : struct { return Compare(ref first, ref second); } private unsafe static int GetHashCode(ref T value, bool salted) { long num = sizeof(T); long num2 = num - 1; if ((ulong)num2 <= 3) { switch (num2) { case 2: goto IL_002f; case 0: goto IL_0038; case 1: goto IL_003c; case 3: goto IL_0040; } } if (num != 8) goto IL_002f; int num3 = ((ulong)value).GetHashCode(); goto IL_004a; IL_0038: num3 = *(sbyte*)(&value); goto IL_004a; IL_003c: num3 = *(short*)(&value); goto IL_004a; IL_004a: if (salted) num3 += RandomExtensions.BitwiseHashSalt; return num3; IL_0040: num3 = *(int*)(&value); goto IL_004a; IL_002f: return Memory.GetHashCode32Aligned((IntPtr)(&value), num, salted); } public static int GetHashCode(T value, bool salted = true) { return GetHashCode(ref value, salted); } private unsafe static int GetHashCode(ref T value, int hash, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<int, int, int> hashFunction, bool salted) { return Memory.GetHashCode32Aligned((IntPtr)(&value), sizeof(T), hash, ref hashFunction, salted); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetHashCode(T value, int hash, Func<int, int, int> hashFunction, bool salted = true) { ValueFunc<int, int, int> hashFunction2 = new ValueFunc<int, int, int>(hashFunction, true); return GetHashCode(ref value, hash, ref hashFunction2, salted); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetHashCode(T value, int hash, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<int, int, int> hashFunction, bool salted = true) { return GetHashCode(ref value, hash, ref hashFunction, salted); } bool IEqualityComparer<T>.Equals(T x, T y) { return Equals(ref x, ref y); } int IEqualityComparer<T>.GetHashCode(T obj) { return GetHashCode(ref obj, true); } int IComparer<T>.Compare(T x, T y) { return Compare(ref x, ref y); } } }