BitwiseComparer<T>
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);
}
}
}