Innovenergy_trunk/csharp/Lib/Utils/Utils.cs

177 lines
5.1 KiB
C#

using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.CompilerServices;
using static System.Runtime.CompilerServices.MethodImplOptions;
namespace InnovEnergy.Lib.Utils;
public static class Utils
{
public static Boolean IsNull<T>([NotNullWhen(returnValue: false)] this T t) => t is null;
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)]
public static T ConvertTo<T>(this IConvertible convertible) where T : IConvertible
{
return (T)ConvertTo(convertible, typeof(T));
}
[DebuggerStepThrough][MethodImpl(AggressiveInlining)]
public static Object ConvertTo(this IConvertible convertible, Type type)
{
var t = type.IsEnum
? Enum.GetUnderlyingType(type)
: type;
return Convert.ChangeType(convertible, t, CultureInfo.InvariantCulture);
}
public static T Do<T>(this T t, Action action)
{
action();
return t;
}
[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;
}
// 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);
// }
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
public static R Apply<T, R>(this T t, Func<T, R> f) => f(t);
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
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);
[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
? res
: res + length;
}
public static Decimal Modulo(this Decimal dividend, Decimal divisor)
{
var res = dividend % divisor;
return res >= 0
? res
: res + divisor;
}
public static Int32 Clamp(this Int32 value, Int32 minValue, Int32 maxValue)
{
if (minValue > maxValue)
throw new ArgumentException();
var clamped = Math.Min(maxValue, value);
clamped = Math.Max(minValue, clamped);
return clamped;
}
public static Double Clamp(this Double value, Double minValue, Double maxValue)
{
if (minValue > maxValue)
throw new ArgumentException();
var clamped = Math.Min(maxValue, value);
clamped = Math.Max(minValue, clamped);
return clamped;
}
public static Double ClampMax(this Double value, Double maxValue)
{
return Math.Min(maxValue, value);
}
public static Double ClampMin(this Double value, Double minValue)
{
return Math.Max(minValue, value);
}
public static Decimal Clamp(this Decimal value, Decimal minValue, Decimal maxValue)
{
var clamped = Math.Min(maxValue, value);
clamped = Math.Max(minValue, clamped);
return clamped;
}
public static R ValueOrDefault<T, R>(this Dictionary<T, R> dict, T key, R defaultValue) where T : notnull
{
return dict.TryGetValue(key, out var value)
? value
: defaultValue;
}
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;
}