using System;
using System.Collections.Generic;
using System.Text;
namespace Compatibility.Linq
{
/// <summary>A structure that provides Linq functionality in C# 2.0</summary>
/// <typeparam name="T">Type of elements in the sequence to be processed</typeparam>
/// <remarks>Please note that if you have access to C# 3.0, you do not need to
/// use this class. Even if you are using .NET Framework 2.0, C# still allows
/// you to use LINQ syntax; just add a reference to LinqBridge.dll in your
/// project (LinqBridge provides an implementation of LINQ to Objects for the
/// .NET framework 2.0. It is included in the Loyc distribution.
///
/// PoorMansLinq(of T) does not include all functionality of the static class
/// Enumerable. It cannot not include specializations for specific kinds of T,
/// such as Average<double>(). Nor does it include static methods such as
/// Empty() and Range(first, last) that are not extension methods. And it
/// doesn't include AsEnumerable(), which makes no sense without the extension
/// methods feature.
/// </remarks>
public struct PoorMansLinq<T> : IEnumerable<T>
{
public IEnumerable<T> Collection;
public PoorMansLinq(IEnumerable<T> collection) { Collection = collection; }
#region Aggregate
public T Aggregate(Func<T, T, T> func)
{ return Enumerable.Aggregate(Collection, func); }
public TAccumulate Aggregate<TAccumulate>(TAccumulate seed, Func<TAccumulate, T, TAccumulate> func)
{ return Enumerable.Aggregate<T, TAccumulate>(Collection, seed, func); }
public TResult Aggregate<TAccumulate, TResult>(TAccumulate seed, Func<TAccumulate, T, TAccumulate> func, Func<TAccumulate, TResult> resultSelector)
{ return Enumerable.Aggregate<T, TAccumulate, TResult>(Collection, seed, func, resultSelector); }
#endregion
#region All
public bool All(Func<T, bool> predicate)
{ return Enumerable.All<T>(Collection, predicate); }
#endregion
#region Any
public bool Any()
{ return Enumerable.Any<T>(Collection); }
public bool Any(Func<T, bool> predicate)
{ return Enumerable.Any<T>(Collection); }
#endregion
#region Average
/*
// The following overloads cannot be supported here. Call Enumerable.Average() instead.
public double Average(this IEnumerable<int> source)
public double? Average(this IEnumerable<int?> source)
public double Average(this IEnumerable<long> source)
public double? Average(this IEnumerable<long?> source)
public double Average(this IEnumerable<double> source)
public double? Average(this IEnumerable<double?> source)
public decimal Average(this IEnumerable<decimal> source)
public decimal? Average(this IEnumerable<decimal?> source)
*/
public double Average(Func<T, int> selector)
{ return Enumerable.Average<T>(Collection, selector); }
public double? Average(Func<T, int?> selector)
{ return Enumerable.Average<T>(Collection, selector); }
public double Average(Func<T, long> selector)
{ return Enumerable.Average<T>(Collection, selector); }
public double? Average(Func<T, long?> selector)
{ return Enumerable.Average<T>(Collection, selector); }
public double Average(Func<T, double> selector)
{ return Enumerable.Average<T>(Collection, selector); }
public double? Average(Func<T, double?> selector)
{ return Enumerable.Average<T>(Collection, selector); }
public decimal Average(Func<T, decimal> selector)
{ return Enumerable.Average<T>(Collection, selector); }
public decimal? Average(Func<T, decimal?> selector)
{ return Enumerable.Average<T>(Collection, selector); }
#endregion
#region Concat
public PoorMansLinq<T> Concat(IEnumerable<T> second)
{ return new PoorMansLinq<T>(Enumerable.Concat(Collection, second)); }
#endregion
#region Contains
public bool Contains(T value)
{ return Enumerable.Contains<T>(Collection, value); }
public bool Contains(T value, IEqualityComparer<T> comparer)
{ return Enumerable.Contains<T>(Collection, value, comparer); }
#endregion
#region Count
public int Count()
{ return Enumerable.Count<T>(Collection); }
public int Count(Func<T, bool> selector)
{ return Enumerable.Count<T>(Collection, selector); }
#endregion
#region DefaultIfEmpty
public PoorMansLinq<T> DefaultIfEmpty()
{ return new PoorMansLinq<T>(Enumerable.DefaultIfEmpty(Collection)); }
public PoorMansLinq<T> DefaultIfEmpty(T defaultValue)
{ return new PoorMansLinq<T>(Enumerable.DefaultIfEmpty(Collection, defaultValue)); }
#endregion
#region Distinct
public PoorMansLinq<T> Distinct()
{ return new PoorMansLinq<T>(Enumerable.Distinct<T>(Collection)); }
public PoorMansLinq<T> Distinct(IEqualityComparer<T> comparer)
{ return new PoorMansLinq<T>(Enumerable.Distinct<T>(Collection, comparer)); }
#endregion
#region ElementAt
public T ElementAt(int index)
{ return Enumerable.ElementAt<T>(Collection, index); }
#endregion
#region ElementAtOrDefault
public T ElementAtOrDefault(int index)
{ return Enumerable.ElementAtOrDefault<T>(Collection, index); }
#endregion
#region Except
public PoorMansLinq<T> Except(IEnumerable<T> second)
{ return new PoorMansLinq<T>(Enumerable.Except<T>(Collection, second)); }
public PoorMansLinq<T> Except(IEnumerable<T> second, IEqualityComparer<T> comparer)
{ return new PoorMansLinq<T>(Enumerable.Except<T>(Collection, second, comparer)); }
#endregion
#region First
public T First()
{ return Enumerable.First<T>(Collection); }
public T First(Func<T, bool> predicate)
{ return Enumerable.First<T>(Collection, predicate); }
#endregion
#region FirstOrDefault
public T FirstOrDefault()
{ return Enumerable.FirstOrDefault<T>(Collection); }
public T FirstOrDefault(Func<T, bool> predicate)
{ return Enumerable.FirstOrDefault<T>(Collection, predicate); }
#endregion
#region GroupBy
public PoorMansLinq<IGrouping<TKey, T>> GroupBy<TKey>
(Func<T, TKey> keySelector)
{ return new PoorMansLinq<IGrouping<TKey, T>>(Enumerable.GroupBy<T, TKey>(Collection, keySelector)); }
public PoorMansLinq<IGrouping<TKey, T>> GroupBy<TKey>
(Func<T, TKey> keySelector, IEqualityComparer<TKey> comparer)
{ return new PoorMansLinq<IGrouping<TKey, T>>(Enumerable.GroupBy<T, TKey>(Collection, keySelector, comparer)); }
public PoorMansLinq<IGrouping<TKey, TElement>> GroupBy<TKey, TElement>
(Func<T, TKey> keySelector, Func<T, TElement> elementSelector)
{ return new PoorMansLinq<IGrouping<TKey, TElement>>(Enumerable.GroupBy<T, TKey, TElement>(Collection, keySelector, elementSelector)); }
public PoorMansLinq<IGrouping<TKey, TElement>> GroupBy<TKey, TElement>
(Func<T, TKey> keySelector, Func<T, TElement> elementSelector, IEqualityComparer<TKey> comparer)
{ return new PoorMansLinq<IGrouping<TKey, TElement>>(Enumerable.GroupBy<T, TKey, TElement>(Collection, keySelector, elementSelector, comparer)); }
#endregion
# region GroupJoin
public PoorMansLinq<TResult> GroupJoin<TInner, TKey, TResult>
(IEnumerable<TInner> inner, Func<T, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector, Func<T, IEnumerable<TInner>, TResult> resultSelector)
{ return new PoorMansLinq<TResult>(Enumerable.GroupJoin<T, TInner, TKey, TResult>
(Collection, inner, outerKeySelector, innerKeySelector, resultSelector)); }
public PoorMansLinq<TResult> GroupJoin<TInner, TKey, TResult>
(IEnumerable<TInner> inner, Func<T, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector, Func<T, IEnumerable<TInner>, TResult> resultSelector,
IEqualityComparer<TKey> comparer)
{ return new PoorMansLinq<TResult>(Enumerable.GroupJoin<T, TInner, TKey, TResult>
(Collection, inner, outerKeySelector, innerKeySelector, resultSelector, comparer)); }
#endregion
#region Intersect
public PoorMansLinq<T> Intersect(IEnumerable<T> second)
{ return new PoorMansLinq<T>(Enumerable.Intersect<T>(Collection, second)); }
#endregion
#region Join
public PoorMansLinq<TResult> Join<TInner, TKey, TResult>
(IEnumerable<TInner> inner, Func<T, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector, Func<T, TInner, TResult> resultSelector)
{ return new PoorMansLinq<TResult>(Enumerable.Join<T, TInner, TKey, TResult>
(Collection, inner, outerKeySelector, innerKeySelector, resultSelector)); }
public PoorMansLinq<TResult> Join<TInner, TKey, TResult>
(IEnumerable<TInner> inner, Func<T, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector, Func<T, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)
{ return new PoorMansLinq<TResult>(Enumerable.Join<T, TInner, TKey, TResult>
(Collection, inner, outerKeySelector, innerKeySelector, resultSelector, comparer)); }
#endregion
#region Last
public T Last()
{ return Enumerable.Last<T>(Collection); }
public T Last(Func<T, bool> predicate)
{ return Enumerable.Last<T>(Collection, predicate); }
#endregion
#region LastOrDefault
public T LastOrDefault()
{ return Enumerable.LastOrDefault<T>(Collection); }
public T LastOrDefault(Func<T, bool> predicate)
{ return Enumerable.LastOrDefault<T>(Collection, predicate); }
#endregion
#region LongCount
public long LongCount()
{ return Enumerable.LongCount<T>(Collection); }
public long LongCount(Func<T, bool> selector)
{ return Enumerable.LongCount<T>(Collection, selector); }
#endregion
#region Max
/*
// The following overloads cannot be supported here. Call Enumerable.Max() instead.
public int Max(this IEnumerable<int> source)
public int? Max(this IEnumerable<int?> source)
public long Max(this IEnumerable<long> source)
public long? Max(this IEnumerable<long?> source)
public double Max(this IEnumerable<double> source)
public double? Max(this IEnumerable<double?> source)
public decimal Max(this IEnumerable<decimal> source)
public decimal? Max(this IEnumerable<decimal?> source)
*/
public T Max()
{ return Enumerable.Max<T>(Collection); }
public int Max(Func<T, int> selector)
{ return Enumerable.Max<T>(Collection, selector); }
public int? Max(Func<T, int?> selector)
{ return Enumerable.Max<T>(Collection, selector); }
public long Max(Func<T, long> selector)
{ return Enumerable.Max<T>(Collection, selector); }
public long? Max(Func<T, long?> selector)
{ return Enumerable.Max<T>(Collection, selector); }
public double Max(Func<T, double> selector)
{ return Enumerable.Max<T>(Collection, selector); }
public double? Max(Func<T, double?> selector)
{ return Enumerable.Max<T>(Collection, selector); }
public decimal Max(Func<T, decimal> selector)
{ return Enumerable.Max<T>(Collection, selector); }
public decimal? Max(Func<T, decimal?> selector)
{ return Enumerable.Max<T>(Collection, selector); }
public TResult Max<TResult>(Func<T, TResult> selector)
{ return Enumerable.Max<T, TResult>(Collection, selector); }
#endregion
#region Min
/*
// The following overloads cannot be supported here. Call Enumerable.Min() instead.
public int Min(this IEnumerable<int> source)
public int? Min(this IEnumerable<int?> source)
public long Min(this IEnumerable<long> source)
public long? Min(this IEnumerable<long?> source)
public double Min(this IEnumerable<double> source)
public double? Min(this IEnumerable<double?> source)
public decimal Min(this IEnumerable<decimal> source)
public decimal? Min(this IEnumerable<decimal?> source)
*/
public T Min()
{ return Enumerable.Min<T>(Collection); }
public int Min(Func<T, int> selector)
{ return Enumerable.Min<T>(Collection, selector); }
public int? Min(Func<T, int?> selector)
{ return Enumerable.Min<T>(Collection, selector); }
public long Min(Func<T, long> selector)
{ return Enumerable.Min<T>(Collection, selector); }
public long? Min(Func<T, long?> selector)
{ return Enumerable.Min<T>(Collection, selector); }
public double Min(Func<T, double> selector)
{ return Enumerable.Min<T>(Collection, selector); }
public double? Min(Func<T, double?> selector)
{ return Enumerable.Min<T>(Collection, selector); }
public decimal Min(Func<T, decimal> selector)
{ return Enumerable.Min<T>(Collection, selector); }
public decimal? Min(Func<T, decimal?> selector)
{ return Enumerable.Min<T>(Collection, selector); }
public TResult Min<TResult>(Func<T, TResult> selector)
{ return Enumerable.Min<T, TResult>(Collection, selector); }
#endregion
#region OrderBy
public PoorMansLinq<T> OrderBy<TKey>(Func<T, TKey> keySelector)
{ return new PoorMansLinq<T>(Enumerable.OrderBy(Collection, keySelector)); }
public PoorMansLinq<T> OrderBy<TKey>
(Func<T, TKey> keySelector, IComparer<TKey> comparer)
{ return new PoorMansLinq<T>(Enumerable.OrderBy(Collection, keySelector, comparer)); }
#endregion
#region OrderByDescending
public PoorMansLinq<T> OrderByDescending<TKey>
(Func<T, TKey> keySelector)
{ return new PoorMansLinq<T>(Enumerable.OrderByDescending<T, TKey>(Collection, keySelector)); }
public PoorMansLinq<T> OrderByDescending<TKey>
(Func<T, TKey> keySelector, IComparer<TKey> comparer)
{ return new PoorMansLinq<T>(Enumerable.OrderByDescending<T, TKey>(Collection, keySelector, comparer)); }
#endregion
#region Reverse
public PoorMansLinq<T> Reverse()
{ return new PoorMansLinq<T>(Enumerable.Reverse(Collection)); }
#endregion
#region Select
public PoorMansLinq<TResult> Select<TResult>(Func<T, TResult> selector)
{ return new PoorMansLinq<TResult>(Enumerable.Select<T, TResult> (Collection, selector)); }
public PoorMansLinq<TResult> Select<TResult>(Func<T, int, TResult> selector)
{ return new PoorMansLinq<TResult>(Enumerable.Select<T, TResult> (Collection, selector)); }
#endregion
#region SelectMany
public PoorMansLinq<TResult> SelectMany<TResult>(Func<T, IEnumerable<TResult>> selector)
{ return new PoorMansLinq<TResult>(Enumerable.SelectMany<T, TResult>(Collection, selector)); }
public PoorMansLinq<TResult> SelectMany<TResult>(Func<T, int, IEnumerable<TResult>> selector)
{ return new PoorMansLinq<TResult>(Enumerable.SelectMany<T, TResult>(Collection, selector)); }
#endregion
#region Single
public T Single()
{ return Enumerable.Single<T>(Collection); }
public T Single(Func<T, bool> predicate)
{ return Enumerable.Single<T>(Collection, predicate); }
#endregion
#region SingleOrDefault
public T SingleOrDefault()
{ return Enumerable.SingleOrDefault<T>(Collection); }
public T SingleOrDefault(Func<T, bool> predicate)
{ return Enumerable.SingleOrDefault<T>(Collection, predicate); }
#endregion
#region Skip
public PoorMansLinq<T> Skip(int count)
{ return new PoorMansLinq<T>(Enumerable.Skip<T>(Collection, count)); }
#endregion
#region SkipWhile
public PoorMansLinq<T> SkipWhile(Func<T, bool> predicate)
{ return new PoorMansLinq<T>(Enumerable.SkipWhile<T>(Collection, predicate)); }
public PoorMansLinq<T> SkipWhile(Func<T, int, bool> predicate)
{ return new PoorMansLinq<T>(Enumerable.SkipWhile(Collection, predicate)); }
#endregion
#region Sum
/*
// The following overloads cannot be supported here. Call Enumerable.Sum() instead.
public int Sum(this IEnumerable<int> source)
public int? Sum(this IEnumerable<int?> source)
public long Sum(this IEnumerable<long> source)
public long? Sum(this IEnumerable<long?> source)
public double Sum(this IEnumerable<double> source)
public double? Sum(this IEnumerable<double?> source)
public decimal Sum(this IEnumerable<decimal> source)
public decimal? Sum(this IEnumerable<decimal?> source)
*/
public int Sum(Func<T, int> selector)
{ return Enumerable.Sum<T>(Collection, selector); }
public int? Sum(Func<T, int?> selector)
{ return Enumerable.Sum<T>(Collection, selector); }
public long Sum(Func<T, long> selector)
{ return Enumerable.Sum<T>(Collection, selector); }
public long? Sum(Func<T, long?> selector)
{ return Enumerable.Sum<T>(Collection, selector); }
public double Sum(Func<T, double> selector)
{ return Enumerable.Sum<T>(Collection, selector); }
public double? Sum(Func<T, double?> selector)
{ return Enumerable.Sum<T>(Collection, selector); }
public decimal Sum(Func<T, decimal> selector)
{ return Enumerable.Sum<T>(Collection, selector); }
public decimal? Sum(Func<T, decimal?> selector)
{ return Enumerable.Sum<T>(Collection, selector); }
#endregion
#region Take
public PoorMansLinq<T> Take(int count)
{ return new PoorMansLinq<T>(Enumerable.Take<T>(Collection, count)); }
#endregion
#region TakeWhile
public PoorMansLinq<T> TakeWhile(Func<T, bool> predicate)
{ return new PoorMansLinq<T>(Enumerable.TakeWhile<T>(Collection, predicate)); }
public PoorMansLinq<T> TakeWhile(Func<T, int, bool> predicate)
{ return new PoorMansLinq<T>(Enumerable.TakeWhile<T>(Collection, predicate)); }
#endregion
#region ThenBy
public PoorMansLinq<T> ThenBy<TKey>(Func<T, TKey> keySelector)
{ return new PoorMansLinq<T>(Enumerable.ThenBy<T, TKey>((OrderedSequence<T>)Collection, keySelector)); }
public PoorMansLinq<T> ThenBy<TKey>
(Func<T, TKey> keySelector, IComparer<TKey> comparer)
{ return new PoorMansLinq<T>(Enumerable.ThenBy<T, TKey>((OrderedSequence<T>)Collection, keySelector, comparer)); }
#endregion
#region ThenByDescending
public PoorMansLinq<T> ThenByDescending<TKey>(Func<T, TKey> keySelector)
{ return new PoorMansLinq<T>(Enumerable.ThenBy<T, TKey>((OrderedSequence<T>)Collection, keySelector)); }
public PoorMansLinq<T> ThenByDescending<TKey>
(Func<T, TKey> keySelector, IComparer<TKey> comparer)
{ return new PoorMansLinq<T>(Enumerable.ThenBy<T, TKey>((OrderedSequence<T>)Collection, keySelector, comparer)); }
#endregion
#region ToArray
public T[] ToArray()
{ return Enumerable.ToArray<T>(Collection); }
#endregion
#region ToDictionary
public Dictionary<TKey, TElement> ToDictionary<TKey, TElement>
(Func<T, TKey> keySelector, Func<T, TElement> elementSelector)
{ return Enumerable.ToDictionary<T, TKey, TElement>(Collection, keySelector, elementSelector); }
public Dictionary<TKey, TElement> ToDictionary<TKey, TElement>
(Func<T, TKey> keySelector, Func<T, TElement> elementSelector, IEqualityComparer<TKey> comparer)
{ return Enumerable.ToDictionary<T, TKey, TElement>(Collection, keySelector, elementSelector, comparer); }
#endregion
#region ToList
public List<T> ToList()
{ return Enumerable.ToList<T>(Collection); }
#endregion
#region ToLookup
public Lookup<TKey, T> ToLookup<TKey>(Func<T, TKey> keySelector)
{ return Enumerable.ToLookup<T, TKey>(Collection, keySelector); }
public Lookup<TKey, T> ToLookup<TKey>
(Func<T, TKey> keySelector, IEqualityComparer<TKey> comparer)
{ return Enumerable.ToLookup<T, TKey>(Collection, keySelector, comparer); }
public Lookup<TKey, TElement> ToLookup<TKey, TElement>
(Func<T, TKey> keySelector, Func<T, TElement> elementSelector)
{ return Enumerable.ToLookup<T, TKey, TElement>(Collection, keySelector, elementSelector); }
public Lookup<TKey, TElement> ToLookup<TKey, TElement>
(Func<T, TKey> keySelector, Func<T, TElement> elementSelector, IEqualityComparer<TKey> comparer)
{ return Enumerable.ToLookup<T, TKey, TElement>(Collection, keySelector, elementSelector, comparer); }
#endregion
#region Union
public PoorMansLinq<T> Union(IEnumerable<T> second)
{ return new PoorMansLinq<T>(Enumerable.Union<T>(Collection, second)); }
#endregion
#region Where
public PoorMansLinq<T> Where(Func<T, bool> predicate)
{ return new PoorMansLinq<T>(Enumerable.Where<T>(Collection, predicate)); }
public PoorMansLinq<T> Where(Func<T, int, bool> predicate)
{ return new PoorMansLinq<T>(Enumerable.Where<T>(Collection, predicate)); }
#endregion
#region Cast, OfType
public PoorMansLinq<TResult> Cast<TResult>()
{
return new PoorMansLinq<TResult>(Enumerable.Cast<TResult>(Collection));
}
public PoorMansLinq<TResult> OfType<TResult>()
{
return new PoorMansLinq<TResult>(Enumerable.OfType<TResult>(Collection));
}
#endregion
// These methods are not included in the
// .NET Standard Query Operators Specification,
// but they provide additional useful commands
public int IndexOf(T item, IEqualityComparer<T> comparer)
{ return Enumerable.IndexOf<T>(Collection, item, comparer); }
public int IndexOf(T item)
{ return Enumerable.IndexOf<T>(Collection, item); }
public PoorMansLinq<T> Sorted()
{ return new PoorMansLinq<T>(Enumerable.OrderBy<T, T>(Collection, delegate(T t) { return t; })); }
#region IEnumerable<T> Members
public IEnumerator<T> GetEnumerator()
{
return Collection.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return Collection.GetEnumerator();
}
#endregion
}
}