using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace WPFDark { public static class HashCodeMaker { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int To32(long h64) => (int) ((h64 & 0xFFFFFFFF) ^ ((h64 >> 32) & 0xFFFFFFFF)); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long Make(float x, float y) { unchecked { var ix = (long) Unsafe.As(ref x); var iy = (long) Unsafe.As(ref y); var hashCode = ix; hashCode = (hashCode * 397) ^ iy; return hashCode; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long Make(float x, float y, float z) { unchecked { var ix = (long) Unsafe.As(ref x); var iy = (long) Unsafe.As(ref y); var iz = (long) Unsafe.As(ref z); var hashCode = ix; hashCode = (hashCode * 397) ^ iy; hashCode = (hashCode * 397) ^ iz; return hashCode; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long Make(float x, float y, float z, float w) { unchecked { var ix = (long) Unsafe.As(ref x); var iy = (long) Unsafe.As(ref y); var iz = (long) Unsafe.As(ref z); var iw = (long) Unsafe.As(ref w); var hashCode = ix; hashCode = (hashCode * 397) ^ iy; hashCode = (hashCode * 397) ^ iz; hashCode = (hashCode * 397) ^ iw; return hashCode; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long Make(double x, double y) { unchecked { var ix = Unsafe.As(ref x); var iy = Unsafe.As(ref y); var hashCode = ix; hashCode = (hashCode * 397) ^ iy; return hashCode; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long Make(double x, double y, double z) { unchecked { var ix = Unsafe.As(ref x); var iy = Unsafe.As(ref y); var iz = Unsafe.As(ref z); var hashCode = ix; hashCode = (hashCode * 397) ^ iy; hashCode = (hashCode * 397) ^ iz; return hashCode; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long Make(double x, double y, double z, double w) { unchecked { var ix = Unsafe.As(ref x); var iy = Unsafe.As(ref y); var iz = Unsafe.As(ref z); var iw = Unsafe.As(ref w); var hashCode = ix; hashCode = (hashCode * 397) ^ iy; hashCode = (hashCode * 397) ^ iz; hashCode = (hashCode * 397) ^ iw; return hashCode; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long Make(double v0, double v1, double v2, double v3, double v4, double v5) { unchecked { var iv0 = Unsafe.As(ref v0); var iv1 = Unsafe.As(ref v1); var iv2 = Unsafe.As(ref v2); var iv3 = Unsafe.As(ref v3); var iv4 = Unsafe.As(ref v4); var iv5 = Unsafe.As(ref v5); var hashCode = iv0; hashCode = (hashCode * 397) ^ iv1; hashCode = (hashCode * 397) ^ iv2; hashCode = (hashCode * 397) ^ iv3; hashCode = (hashCode * 397) ^ iv4; hashCode = (hashCode * 397) ^ iv5; return hashCode; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long Make(double x, double y, double z, bool i) { Debug.Assert(Unsafe.SizeOf() == 1); var ii = (long) Unsafe.As(ref i); return Make(x, y, z) ^ ii; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long Make(ByteColor color) { return color.HashCode; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long Make(ByteColor color, double x) { var ix = Unsafe.As(ref x); return ix ^ color.HashCode; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long Make(ByteColor color, bool i) { Debug.Assert(Unsafe.SizeOf() == 1); var ii = (long) Unsafe.As(ref i); return ii ^ color.HashCode; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long Make(ReadOnlySpan x) => Make(MemoryMarshal.Cast(x)); public static long Make(ReadOnlySpan x) { unchecked { long hashCode = 0; var i8Span = MemoryMarshal.Cast(x); foreach (var v in i8Span) hashCode = (hashCode * 397) ^ v; var remainingLength = x.Length & 7; var i1Span = x.Slice(x.Length - remainingLength, remainingLength); ref var i1Ref = ref MemoryMarshal.GetReference(i1Span); switch (remainingLength) { case 0: break; case 1: hashCode = (hashCode * 397) ^ i1Ref; break; case 2: hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned(ref i1Ref); break; case 3: hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned(ref i1Ref); hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref i1Ref, (IntPtr) 2)); break; case 4: hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned(ref i1Ref); break; case 5: hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned(ref i1Ref); hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref i1Ref, (IntPtr) 4)); break; case 6: hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned(ref i1Ref); hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref i1Ref, (IntPtr) 4)); break; case 7: hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned(ref i1Ref); hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref i1Ref, (IntPtr) 4)); hashCode = (hashCode * 397) ^ Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref i1Ref, (IntPtr) 6)); break; } return hashCode; } } } }