using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace IPA.Utilities { /// /// Extensions for that don't currently exist in System.Linq. /// public static class EnumerableExtensions { /// /// Adds a value to the beginning of the sequence. /// /// the type of the elements of /// a sequence of values /// the value to prepend to /// a new sequence beginning with public static IEnumerable Prepend(this IEnumerable seq, T prep) => new PrependEnumerable(seq, prep); private sealed class PrependEnumerable : IEnumerable { private readonly IEnumerable rest; private readonly T first; public PrependEnumerable(IEnumerable rest, T first) { this.rest = rest; this.first = first; } public IEnumerator GetEnumerator() { // TODO: a custom impl that is less garbage yield return first; foreach (var v in rest) yield return v; } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } /// /// Adds a value to the end of the sequence. /// /// the type of the elements of /// a sequence of values /// the value to append to /// a new sequence ending with public static IEnumerable Append(this IEnumerable seq, T app) => new AppendEnumerable(seq, app); private sealed class AppendEnumerable : IEnumerable { private readonly IEnumerable rest; private readonly T last; public AppendEnumerable(IEnumerable rest, T last) { this.rest = rest; this.last = last; } public IEnumerator GetEnumerator() { // TODO: a custom impl that is less garbage foreach (var v in rest) yield return v; yield return last; } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } /// /// LINQ extension method that filters elements out of an enumeration. /// /// the type of the enumeration /// the enumeration to filter /// a filtered enumerable public static IEnumerable NonNull(this IEnumerable self) where T : class => self.Where(o => o != null); /// /// LINQ extension method that filters elements out of an enumeration based on a converter. /// /// the type of the enumeration /// the type to compare to null /// the enumeration to filter /// the predicate to select for filtering /// a filtered enumerable public static IEnumerable NonNull(this IEnumerable self, Func pred) where U : class => self.Where(o => pred(o) != null); /// /// LINQ extension method that filters elements from an enumeration of nullable types. /// /// the underlying type of the nullable enumeration /// the enumeration to filter /// a filtered enumerable public static IEnumerable NonNull(this IEnumerable self) where T : struct => self.Where(o => o != null).Select(o => o.Value); } }