using System.Numerics; namespace Universal; public static class Extensions { public static bool TryGetSubValue(this ConcurrentDictionary> input, TKey1 key1, TKey2 key2, out TValue? value) where TKey1 : notnull where TKey2 : notnull { value = default; if (input is null || key1 is null || key2 is null) return false; if (!input.TryGetValue(key1, out ConcurrentDictionary? output1) || output1 is null) return false; if (!output1.TryGetValue(key2, out value) || value is null) return false; return true; } public static bool TryGetSubValue(this IDictionary> input, TKey1 key1, TKey2 key2, out TValue? value) where TKey1 : notnull where TKey2 : notnull { value = default; if (input is null || key1 is null || key2 is null) return false; if (!input.TryGetValue(key1, out IDictionary? output1) || output1 is null) return false; if (!output1.TryGetValue(key2, out value) || value is null) return false; return true; } public static bool TryGetValueNotNull(this IDictionary input, TKey key, out TValue value) { if (!input.TryGetValue(key, out TValue? output) || output is null) { value = default!; return false; } value = output; return true; } public static bool In(this T input, params T[] values) { return values.Contains(input); } public static int Foreach(this IEnumerable t, Action? action = null) { foreach (var item in t) action?.Invoke(item); return t.Count(); } public static void For(this IEnumerable t, uint startIndex, uint count, Action? action = null) { T[] values = [.. t]; uint endIndex = startIndex + count; for (uint i = startIndex; i < endIndex; i++) action?.Invoke(values[i]); } public static bool InRange(this T t, T leftBorder, T rightBorder, bool startInclude = true, bool endInclude = true) where T : INumber { if (startInclude) { if (t < leftBorder) return false; } else { if (t <= leftBorder) return false; } if (endInclude) { if (t > rightBorder) return false; } else { if (t >= rightBorder) return false; } return true; } public static void ForeachWhere(this IEnumerable t, Action action, Func judger) { foreach (var item in t) { if (!judger.Invoke(item)) continue; action.Invoke(item); } } public static bool TryForeach(this IEnumerable t, Func func) { foreach (var item in t) { if (!func.Invoke(item)) return false; } return true; } public static IEnumerable> Split(this IEnumerable arr, int size) { for (var i = 0; i < arr.Count() / size + 1; i++) yield return arr.Skip(i * size).Take(size); } public static string ToBase64(this string input) { if (string.IsNullOrEmpty(input)) return string.Empty; byte[] bytes = Encoding.ASCII.GetBytes(input); return Convert.ToBase64String(bytes); } public static string FromBase64(this string input) { if (string.IsNullOrEmpty(input)) return string.Empty; byte[] bytes = Convert.FromBase64String(input); return Encoding.ASCII.GetString(bytes); } } //Require C# 14+ #if false public static class ExtensionTest { extension(TSource source) where TSource : INumber { public bool InRange(TSource leftBorder, TSource rightBorder, bool startInclude = true, bool endInclude = true) { if (startInclude) { if (source < leftBorder) return false; } else { if (source <= leftBorder) return false; } if (endInclude) { if (source > rightBorder) return false; } else { if (source >= rightBorder) return false; } return true; } } extension(string input) { public string ToBase64() { if (string.IsNullOrEmpty(input)) return string.Empty; byte[] bytes = Encoding.Default.GetBytes(input); return Convert.ToBase64String(bytes); } public string FromBase64() { if (string.IsNullOrEmpty(input)) return string.Empty; byte[] bytes = Convert.FromBase64String(input); return Encoding.Default.GetString(bytes); } } extension(TSource source) where TSource : struct { public bool ValueIn(params TSource[] values) => values.Contains(source); } extension(TSource source) where TSource : class { public bool ReferenceIn(params TSource[] values) => values.Contains(source); } extension(IEnumerable sources) { public bool IsEmpty => !sources.Any(); public void For(uint startIndex, uint count, Action action) { TSource[] values = [.. sources]; uint endIndex = startIndex + count; for (uint i = startIndex; i < endIndex; i++) action?.Invoke(values[i]); } public void Foreach(Action action) { foreach (TSource source in sources) action?.Invoke(source); } public int ConditionForeach(Action action, Func condition) { int count = 0; foreach (TSource source in sources) { if (!condition.Invoke(source)) continue; action.Invoke(source); count++; } return count; } public IEnumerable> Splits(int size) { for (var i = 0; i < sources.Count() / size + 1; i++) yield return sources.Skip(i * size).Take(size); } } } #endif