|
|
@ -1,4 +1,5 @@ |
|
|
|
using System; |
|
|
|
#nullable enable |
|
|
|
|
|
|
|
using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Collections.Immutable; |
|
|
|
using System.Collections.Immutable; |
|
|
|
using System.Linq; |
|
|
|
using System.Linq; |
|
|
@ -14,13 +15,13 @@ namespace ICSharpCode.Decompiler.Util |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#if !NETCORE
|
|
|
|
#if !NETCORE
|
|
|
|
public static IEnumerable<(A, B)> Zip<A, B>(this IEnumerable<A> input1, IEnumerable<B> input2) |
|
|
|
public static IEnumerable<(A, B)> Zip<A, B>(this IEnumerable<A>? input1, IEnumerable<B>? input2) |
|
|
|
{ |
|
|
|
{ |
|
|
|
return input1.Zip(input2, (a, b) => (a, b)); |
|
|
|
return input1.Zip(input2, (a, b) => (a, b)); |
|
|
|
} |
|
|
|
} |
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
public static IEnumerable<(A, B)> ZipLongest<A, B>(this IEnumerable<A> input1, IEnumerable<B> input2) |
|
|
|
public static IEnumerable<(A?, B?)> ZipLongest<A, B>(this IEnumerable<A> input1, IEnumerable<B> input2) |
|
|
|
{ |
|
|
|
{ |
|
|
|
using (var it1 = input1.GetEnumerator()) |
|
|
|
using (var it1 = input1.GetEnumerator()) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -60,7 +61,7 @@ namespace ICSharpCode.Decompiler.Util |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#if !NETCORE
|
|
|
|
#if !NETCORE
|
|
|
|
public static HashSet<T> ToHashSet<T>(this IEnumerable<T> input) |
|
|
|
public static HashSet<T> ToHashSet<T>(this IEnumerable<T>? input) |
|
|
|
{ |
|
|
|
{ |
|
|
|
return new HashSet<T>(input); |
|
|
|
return new HashSet<T>(input); |
|
|
|
} |
|
|
|
} |
|
|
@ -76,14 +77,14 @@ namespace ICSharpCode.Decompiler.Util |
|
|
|
return input.Skip(input.Count - count); |
|
|
|
return input.Skip(input.Count - count); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static T PopOrDefault<T>(this Stack<T> stack) |
|
|
|
public static T? PopOrDefault<T>(this Stack<T> stack) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (stack.Count == 0) |
|
|
|
if (stack.Count == 0) |
|
|
|
return default(T); |
|
|
|
return default(T); |
|
|
|
return stack.Pop(); |
|
|
|
return stack.Pop(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static T PeekOrDefault<T>(this Stack<T> stack) |
|
|
|
public static T? PeekOrDefault<T>(this Stack<T> stack) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (stack.Count == 0) |
|
|
|
if (stack.Count == 0) |
|
|
|
return default(T); |
|
|
|
return default(T); |
|
|
@ -277,7 +278,7 @@ namespace ICSharpCode.Decompiler.Util |
|
|
|
/// Returns the minimum element.
|
|
|
|
/// Returns the minimum element.
|
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
|
/// <exception cref="InvalidOperationException">The input sequence is empty</exception>
|
|
|
|
/// <exception cref="InvalidOperationException">The input sequence is empty</exception>
|
|
|
|
public static T MinBy<T, K>(this IEnumerable<T> source, Func<T, K> keySelector, IComparer<K> keyComparer) |
|
|
|
public static T MinBy<T, K>(this IEnumerable<T> source, Func<T, K> keySelector, IComparer<K>? keyComparer) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (source == null) |
|
|
|
if (source == null) |
|
|
|
throw new ArgumentNullException(nameof(source)); |
|
|
|
throw new ArgumentNullException(nameof(source)); |
|
|
@ -318,7 +319,7 @@ namespace ICSharpCode.Decompiler.Util |
|
|
|
/// Returns the maximum element.
|
|
|
|
/// Returns the maximum element.
|
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
|
/// <exception cref="InvalidOperationException">The input sequence is empty</exception>
|
|
|
|
/// <exception cref="InvalidOperationException">The input sequence is empty</exception>
|
|
|
|
public static T MaxBy<T, K>(this IEnumerable<T> source, Func<T, K> keySelector, IComparer<K> keyComparer) |
|
|
|
public static T MaxBy<T, K>(this IEnumerable<T> source, Func<T, K> keySelector, IComparer<K>? keyComparer) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (source == null) |
|
|
|
if (source == null) |
|
|
|
throw new ArgumentNullException(nameof(source)); |
|
|
|
throw new ArgumentNullException(nameof(source)); |
|
|
@ -353,12 +354,12 @@ namespace ICSharpCode.Decompiler.Util |
|
|
|
list.RemoveAt(list.Count - 1); |
|
|
|
list.RemoveAt(list.Count - 1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static T OnlyOrDefault<T>(this IEnumerable<T> source, Func<T, bool> predicate) => OnlyOrDefault(source.Where(predicate)); |
|
|
|
public static T? OnlyOrDefault<T>(this IEnumerable<T>? source, Func<T, bool>? predicate) => OnlyOrDefault(source.Where(predicate)); |
|
|
|
|
|
|
|
|
|
|
|
public static T OnlyOrDefault<T>(this IEnumerable<T> source) |
|
|
|
public static T? OnlyOrDefault<T>(this IEnumerable<T> source) |
|
|
|
{ |
|
|
|
{ |
|
|
|
bool any = false; |
|
|
|
bool any = false; |
|
|
|
T first = default; |
|
|
|
T? first = default; |
|
|
|
foreach (var t in source) |
|
|
|
foreach (var t in source) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (any) |
|
|
|
if (any) |
|
|
@ -372,14 +373,14 @@ namespace ICSharpCode.Decompiler.Util |
|
|
|
|
|
|
|
|
|
|
|
#region Aliases/shortcuts for Enumerable extension methods
|
|
|
|
#region Aliases/shortcuts for Enumerable extension methods
|
|
|
|
public static bool Any<T>(this ICollection<T> list) => list.Count > 0; |
|
|
|
public static bool Any<T>(this ICollection<T> list) => list.Count > 0; |
|
|
|
public static bool Any<T>(this T[] array, Predicate<T> match) => Array.Exists(array, match); |
|
|
|
public static bool Any<T>(this T[]? array, Predicate<T>? match) => Array.Exists(array, match); |
|
|
|
public static bool Any<T>(this List<T> list, Predicate<T> match) => list.Exists(match); |
|
|
|
public static bool Any<T>(this List<T> list, Predicate<T>? match) => list.Exists(match); |
|
|
|
|
|
|
|
|
|
|
|
public static bool All<T>(this T[] array, Predicate<T> match) => Array.TrueForAll(array, match); |
|
|
|
public static bool All<T>(this T[]? array, Predicate<T>? match) => Array.TrueForAll(array, match); |
|
|
|
public static bool All<T>(this List<T> list, Predicate<T> match) => list.TrueForAll(match); |
|
|
|
public static bool All<T>(this List<T> list, Predicate<T>? match) => list.TrueForAll(match); |
|
|
|
|
|
|
|
|
|
|
|
public static T FirstOrDefault<T>(this T[] array, Predicate<T> predicate) => Array.Find(array, predicate); |
|
|
|
public static T FirstOrDefault<T>(this T[]? array, Predicate<T>? predicate) => Array.Find(array, predicate); |
|
|
|
public static T FirstOrDefault<T>(this List<T> list, Predicate<T> predicate) => list.Find(predicate); |
|
|
|
public static T FirstOrDefault<T>(this List<T> list, Predicate<T>? predicate) => list.Find(predicate); |
|
|
|
|
|
|
|
|
|
|
|
public static T Last<T>(this IList<T> list) => list[list.Count - 1]; |
|
|
|
public static T Last<T>(this IList<T> list) => list[list.Count - 1]; |
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|