Added pools, IndexedFishMap, IndexedFishSet, fixed bugs related to FishTable.Remove, added Preview.png, various smaller additions, some refactoring too

This commit is contained in:
bbradson
2024-01-27 10:02:57 +01:00
parent cdf209eb02
commit af759661bd
38 changed files with 1879 additions and 642 deletions
@@ -51,7 +51,7 @@ internal static class Convert
try
{
var dm = new DynamicMethod($"ObjectConverter_{from}_{to}", to,
new[] { typeof(object), typeof(IFormatProvider) }, typeof(FromObjectTo<TTo>), true);
[typeof(object), typeof(IFormatProvider)], typeof(FromObjectTo<TTo>), true);
var il = dm.GetILGenerator();
il.Emit(FishTranspiler.This);
@@ -59,7 +59,7 @@ internal static class Convert
if (from.IsValueType)
{
il.Emit(FishTranspiler.Call(typeof(FromObjectTo<TTo>), nameof(UnboxSafely),
generics: new[] { from }));
generics: [from]));
}
il.Emit(FishTranspiler.Argument(1));
@@ -72,8 +72,9 @@ internal static class Convert
}
catch (Exception ex)
{
throw new($"Failed to compile object converter from {from.FullDescription()} to {
to.FullDescription()}\n{ex}");
return ThrowHelper.ThrowInvalidOperationException<Func<object, IFormatProvider, TTo>>(
$"Failed to compile object converter from {from.FullDescription()} to {
to.FullDescription()}\n{ex}");
}
}
@@ -83,7 +84,7 @@ internal static class Convert
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[SecuritySafeCritical]
private static ref T UnboxSafely<T>(object obj) where T : struct
=> ref Unsafe.Unbox<T>(obj is T ? obj : default);
=> ref Unsafe.Unbox<T>(obj is T ? obj : default(T));
private record struct FuncWrapper
{
@@ -163,7 +164,7 @@ internal static class Convert
private static MethodInfo GenerateWrapperMethod(Type from, Type to, MethodBase method)
{
var dm = new DynamicMethod($"Wrapper_op_{from.Name}_{to.Name}", to,
new[] { from.IsValueType ? from.MakeByRefType() : from, typeof(IFormatProvider) }, from, true);
[from.IsValueType ? from.MakeByRefType() : from, typeof(IFormatProvider)], from, true);
var il = dm.GetILGenerator();
il.Emit(FishTranspiler.Argument(0));
@@ -3,6 +3,7 @@
// 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.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Security;
@@ -16,6 +17,7 @@ public static class Equals<T>
= (delegate*<T, T, bool>)FunctionPointers.Equals.EqualsMethods.GetFunctionPointer(typeof(T));
}
[SuppressMessage("Naming", "CA1720")]
public static class Equals
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
@@ -37,6 +39,8 @@ public static class Equals
public static bool IntPtr(IntPtr x, IntPtr y) => x == y;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[SuppressMessage("Globalization", "CA1307")]
[SuppressMessage("Globalization", "CA1309")]
public static bool String(string x, string y) => string.Equals(x, y);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -3,6 +3,7 @@
// 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.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Security;
@@ -16,6 +17,7 @@ public static class EqualsByRef<T>
= (delegate*<ref T, ref T, bool>)EqualsByRef.EqualsMethods.GetFunctionPointer(typeof(T));
}
[SuppressMessage("Naming", "CA1720")]
public static class EqualsByRef
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
@@ -37,6 +39,8 @@ public static class EqualsByRef
public static bool IntPtr(ref IntPtr x, ref IntPtr y) => x == y;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[SuppressMessage("Globalization", "CA1307")]
[SuppressMessage("Globalization", "CA1309")]
public static bool String(ref string x, ref string y) => string.Equals(x, y);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -3,6 +3,7 @@
// 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;
using JetBrains.Annotations;
@@ -14,6 +15,7 @@ public static class GetHashCode<T>
= (delegate*<T, int>)FunctionPointers.GetHashCode.HashCodeMethods.GetFunctionPointer(typeof(T));
}
[SuppressMessage("Naming", "CA1720")]
public static class GetHashCode
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
@@ -3,6 +3,7 @@
// 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;
using JetBrains.Annotations;
@@ -14,6 +15,7 @@ public static class GetHashCodeByRef<T>
= (delegate*<ref T, int>)GetHashCodeByRef.HashCodeMethods.GetFunctionPointer(typeof(T));
}
[SuppressMessage("Naming", "CA1720")]
public static class GetHashCodeByRef
{
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
@@ -11,15 +11,15 @@ using System.Security;
namespace FisheryLib.FunctionPointers;
public abstract class MethodFactory
public abstract class MethodFactory(MethodInfo[] methods, string namePrefix, bool byRef)
{
protected readonly MethodInfo[] _methods;
protected readonly MethodInfo[] _methods = methods;
protected readonly ConcurrentDictionary<Type, MethodInfo> _methodsByType = new();
protected readonly string _namePrefix;
protected readonly string _namePrefix = namePrefix;
protected readonly bool _byRef;
protected readonly bool _byRef = byRef;
public MethodInfo GetGeneric(string name, params Type[] typeArguments)
=> GetNamed(name).MakeGenericMethod(typeArguments);
@@ -64,14 +64,8 @@ public abstract class MethodFactory
=> type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly)
.Where(predicate).ToArray();
protected MethodFactory(MethodInfo[] methods, string namePrefix, bool byRef)
{
_byRef = byRef;
_methods = methods;
_namePrefix = namePrefix;
}
public new class Equals : MethodFactory
public new class Equals(Type type, string dynamicMethodNamePrefix, bool byRef)
: MethodFactory(GetMethodInfoArraySafely(type), dynamicMethodNamePrefix, byRef)
{
protected override MethodInfo GetOrMakeMethodForType(Type type)
=> GetSpecializedMethod(type)
@@ -160,7 +154,7 @@ public abstract class MethodFactory
try
{
var dm = new DynamicMethod($"{_namePrefix}{type.Name}", typeof(bool),
_byRef ? new[] { type.MakeByRefType(), type.MakeByRefType() } : new[] { type, type }, type, true);
_byRef ? [type.MakeByRefType(), type.MakeByRefType()] : [type, type], type, true);
var il = dm.GetILGenerator();
var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
@@ -232,16 +226,12 @@ public abstract class MethodFactory
throw;
}
}
public Equals(Type type, string dynamicMethodNamePrefix, bool byRef)
: base(GetMethodInfoArraySafely(type), dynamicMethodNamePrefix, byRef)
{
}
private delegate TResult ByRefFunc<T1, T2, out TResult>(ref T1 arg1, ref T2 arg2);
}
public class HashCode : MethodFactory
public class HashCode(Type type, string dynamicMethodNamePrefix, bool byRef)
: MethodFactory(GetMethodInfoArraySafely(type), dynamicMethodNamePrefix, byRef)
{
protected override MethodInfo GetOrMakeMethodForType(Type type)
=> GetSpecializedMethod(type)
@@ -325,7 +315,7 @@ public abstract class MethodFactory
try
{
var dm = new DynamicMethod($"{_namePrefix}{type.Name}", typeof(int),
_byRef ? new[] { type.MakeByRefType() } : new[] { type }, type, true);
_byRef ? [type.MakeByRefType()] : [type], type, true);
var il = dm.GetILGenerator();
var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
@@ -382,11 +372,6 @@ public abstract class MethodFactory
}
}
public HashCode(Type type, string dynamicMethodNamePrefix, bool byRef)
: base(GetMethodInfoArraySafely(type), dynamicMethodNamePrefix, byRef)
{
}
private delegate int ByRefHashCodeGetter<T>(ref T arg);
private delegate int HashCodeGetter<in T>(T arg);
}