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);
}
}