// Copyright (c) 2022 bradson // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace FisheryLib; public static class HashCode { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe int Get([AllowNull] T obj) => FunctionPointers.GetHashCode.Default(obj!); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe int Get([AllowNull] ref T obj) => FunctionPointers.GetHashCodeByRef.Default(ref obj!); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int Combine(T_first first, T_second second) //where T_first : notnull where T_second : notnull => Combine(Get(first), Get(second)); // https://stackoverflow.com/questions/1646807/quick-and-simple-hash-code-combinations/34006336#34006336 [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int Combine(int first, int second) => unchecked((1009 * 9176) + first).CombineWith(second); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int Combine(T_first first, T_second second, T_third third) //where T_first : notnull where T_second : notnull where T_third : notnull => Combine(first, second).CombineWith(third); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int Combine(int first, int second, int third) => Combine(first, second).CombineWith(third); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int Combine(T_first first, T_second second, T_third third, T_fourth fourth) //where T_first : notnull where T_second : notnull where T_third : notnull where T_fourth : notnull => Combine(first, second, third).CombineWith(fourth); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int Combine(int first, int second, int third, int fourth) => Combine(first, second, third).CombineWith(fourth); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int CombineWith(this int first, int second) => unchecked((first * 9176) + second); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int CombineWith(this int first, T second) //where T : notnull => unchecked((first * 9176) + Get(second)); }