using System; using System.Collections.Generic; using System.Linq; namespace ICSharpCode.Decompiler.Util { static class CollectionExtensions { public static void Deconstruct(this KeyValuePair pair, out K key, out V value) { key = pair.Key; value = pair.Value; } public static HashSet ToHashSet(this IEnumerable input) { return new HashSet(input); } public static IEnumerable SkipLast(this IReadOnlyCollection input, int count) { return input.Take(input.Count - count); } public static T PopOrDefault(this Stack stack) { if (stack.Count == 0) return default(T); return stack.Pop(); } public static T PeekOrDefault(this Stack stack) { if (stack.Count == 0) return default(T); return stack.Peek(); } public static int MaxOrDefault(this IEnumerable input, Func selector, int defaultValue = 0) { int max = defaultValue; foreach (var element in input) { int value = selector(element); if (value > max) max = value; } return max; } public static void AddRange(this ICollection collection, IEnumerable input) { foreach (T item in input) collection.Add(item); } /// /// Equivalent to collection.Select(func).ToArray(), but more efficient as it makes /// use of the input collection's known size. /// public static U[] SelectArray(this ICollection collection, Func func) { U[] result = new U[collection.Count]; int index = 0; foreach (var element in collection) { result[index++] = func(element); } return result; } /// /// Equivalent to collection.Select(func).ToList(), but more efficient as it makes /// use of the input collection's known size. /// public static List SelectList(this ICollection collection, Func func) { List result = new List(collection.Count); foreach (var element in collection) { result.Add(func(element)); } return result; } public static IEnumerable SelectWithIndex(this IEnumerable source, Func func) { int index = 0; foreach (var element in source) yield return func(index++, element); } /// /// The merge step of merge sort. /// public static IEnumerable Merge(this IEnumerable input1, IEnumerable input2, Comparison comparison) { var enumA = input1.GetEnumerator(); var enumB = input2.GetEnumerator(); bool moreA = enumA.MoveNext(); bool moreB = enumB.MoveNext(); while (moreA && moreB) { if (comparison(enumA.Current, enumB.Current) <= 0) { yield return enumA.Current; moreA = enumA.MoveNext(); } else { yield return enumB.Current; moreB = enumB.MoveNext(); } } while (moreA) { yield return enumA.Current; moreA = enumA.MoveNext(); } while (moreB) { yield return enumB.Current; moreB = enumB.MoveNext(); } } } }