Innovenergy_trunk/csharp/Lib/Utils/Utils.cs

182 lines
5.2 KiB
C#
Raw Normal View History

2023-10-02 13:36:50 +00:00
using System.Collections.Concurrent;
2023-02-16 12:57:06 +00:00
using System.Diagnostics;
2023-06-13 11:04:07 +00:00
using System.Globalization;
2023-02-16 12:57:06 +00:00
using System.Runtime.CompilerServices;
using static System.Runtime.CompilerServices.MethodImplOptions;
namespace InnovEnergy.Lib.Utils;
2023-02-16 12:57:06 +00:00
public static class Utils
{
2023-02-16 12:57:06 +00:00
public static IEnumerable<String> GetEnumStrings<T>(this T e) where T : Enum
{
return GetEnumValues<T>().Select(v => v.ToString());
}
public static IReadOnlyList<TEnum> GetEnumValues<TEnum>() where TEnum : Enum
{
return (TEnum[]) Enum.GetValues(typeof(TEnum));
}
[DebuggerStepThrough][MethodImpl(AggressiveInlining)]
2023-06-13 11:04:07 +00:00
public static T ConvertTo<T>(this IConvertible convertible) where T : IConvertible
2023-02-16 12:57:06 +00:00
{
2023-06-13 11:04:07 +00:00
return (T)ConvertTo(convertible, typeof(T));
}
2023-02-16 12:57:06 +00:00
2023-06-13 11:04:07 +00:00
[DebuggerStepThrough][MethodImpl(AggressiveInlining)]
public static Object ConvertTo(this IConvertible convertible, Type type)
{
var t = type.IsEnum
? Enum.GetUnderlyingType(type)
: type;
2023-02-16 12:57:06 +00:00
2023-06-13 11:04:07 +00:00
return Convert.ChangeType(convertible, t, CultureInfo.InvariantCulture);
2023-02-16 12:57:06 +00:00
}
2023-03-21 12:46:15 +00:00
public static T Do<T>(this T t, Action action)
{
action();
return t;
}
2023-02-16 12:57:06 +00:00
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
public static void Nop<T>(T _) {}
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
public static T Id<T>(T t) => t;
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
public static T CastTo<T>(this Object source) => (T) source;
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
public static T Apply<T>(this T t, Action<T> f)
{
f(t);
return t;
}
2023-08-18 13:57:00 +00:00
// Below does not work ;(
// [DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
// public static R Apply<T, S, R>(this T t, Func<S, R> f) where T : S
// {
// return f(t);
// }
2023-02-16 12:57:06 +00:00
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
public static R Apply<T, R>(this T t, Func<T, R> f) => f(t);
2023-06-13 11:04:07 +00:00
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
2023-02-16 12:57:06 +00:00
public static R Apply<T1, T2, R>(this (T1 p1, T2 p2) t, Func<T1, T2, R> f) => f(t.p1, t.p2);
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
public static R Apply<T1, T2, T3, R>(this (T1 p1, T2 p2, T3 p3) t, Func<T1, T2, T3, R> f) => f(t.p1, t.p2, t.p3);
2023-02-16 12:57:06 +00:00
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
public static R ApplyOrDefault<T, R>(this T t, Func<T, R> f, R @default)
{
try
{
return f(t);
}
catch
{
return @default;
}
}
public static Int32 Modulo(this Int32 index, Int32 length)
{
var res = index % length;
return res >= 0
2023-02-25 15:16:12 +00:00
? res
: res + length;
2023-02-16 12:57:06 +00:00
}
public static Decimal Modulo(this Decimal dividend, Decimal divisor)
{
var res = dividend % divisor;
return res >= 0
? res
: res + divisor;
}
2023-02-16 12:57:06 +00:00
public static Int32 Clamp(this Int32 value, Int32 minValue, Int32 maxValue)
{
if (minValue > maxValue)
throw new ArgumentException();
2023-02-16 12:57:06 +00:00
var clamped = Math.Min(maxValue, value);
clamped = Math.Max(minValue, clamped);
2023-02-16 12:57:06 +00:00
return clamped;
}
2023-02-16 12:57:06 +00:00
public static Double Clamp(this Double value, Double minValue, Double maxValue)
{
if (minValue > maxValue)
throw new ArgumentException();
2023-02-16 12:57:06 +00:00
var clamped = Math.Min(maxValue, value);
clamped = Math.Max(minValue, clamped);
2023-02-16 12:57:06 +00:00
return clamped;
}
2023-06-20 13:34:04 +00:00
public static Double ClampMax(this Double value, Double maxValue)
{
return Math.Min(maxValue, value);
}
2023-06-20 13:34:04 +00:00
public static Double ClampMin(this Double value, Double minValue)
{
return Math.Max(minValue, value);
}
2023-02-16 12:57:06 +00:00
public static Decimal Clamp(this Decimal value, Decimal minValue, Decimal maxValue)
{
var clamped = Math.Min(maxValue, value);
clamped = Math.Max(minValue, clamped);
return clamped;
2023-02-16 12:57:06 +00:00
}
public static R ValueOrDefault<T, R>(this Dictionary<T, R> dict, T key, R defaultValue) where T : notnull
2023-02-16 12:57:06 +00:00
{
return dict.TryGetValue(key, out var value)
? value
: defaultValue;
2023-02-16 12:57:06 +00:00
}
public static void CopyFilesRecursively(String source, String target)
{
CopyFilesRecursively(new DirectoryInfo(source), new DirectoryInfo(target));
}
public static void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target)
{
foreach (var file in source.GetFiles())
file.CopyTo(Path.Combine(target.FullName, file.Name));
foreach (var dir in source.GetDirectories())
CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name));
}
public static String ExecutingProcessName => Process.GetCurrentProcess().ProcessName;
2023-10-02 13:36:50 +00:00
public static Func<A, R> Memoize<A, R>(Func<A, R> func) where A : notnull
{
var cache = new ConcurrentDictionary<A, R>();
return arg => cache.GetOrAdd(arg, func);
}
2023-02-16 12:57:06 +00:00
}