1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 
5 // Taken from Mono sources, changed to work on C# 2.0 compilers
6 
7 //
8 // Enumerable.cs
9 //
10 // Authors:
11 //  Marek Safar (marek.safar@gmail.com)
12 //  Antonello Provenzano  <antonello@deveel.com>
13 //  Alejandro Serrano "Serras" (trupill@yahoo.es)
14 //  Jb Evain (jbevain@novell.com)
15 //
16 // Copyright (C) 2007 Novell, Inc (http://www.novell.com)
17 //
18 // Permission is hereby granted, free of charge, to any person obtaining
19 // a copy of this software and associated documentation files (the
20 // "Software"), to deal in the Software without restriction, including
21 // without limitation the rights to use, copy, modify, merge, publish,
22 // distribute, sublicense, and/or sell copies of the Software, and to
23 // permit persons to whom the Software is furnished to do so, subject to
24 // the following conditions:
25 //
26 // The above copyright notice and this permission notice shall be
27 // included in all copies or substantial portions of the Software.
28 //
29 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 //
37 
38 // precious: http://www.hookedonlinq.com
39 
Func()40 public delegate TResult Func<TResult>();
Func(T arg1)41 public delegate TResult Func<T, TResult>(T arg1);
Func(T1 arg1, T2 arg2)42 public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
Func(T1 arg1, T2 arg2, T3 arg3)43 public delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4)44 public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
45 
46 
47 namespace Antlr.Runtime.JavaExtensions {
48     static class EnumerableExtensions {
49 
50         #region Average
51 
Average(IEnumerable<int> source)52         public static double Average(IEnumerable<int> source) {
53             return Average<int, long, double>(source, delegate(long a, int b) { return a + b; }, delegate(long a, long b) { return (double)a / (double)b; });
54         }
55 
56         static TResult Average<TElement, TAggregate, TResult>(IEnumerable<TElement> source,
57             Func<TAggregate, TElement, TAggregate> func, Func<TAggregate, long, TResult> result)
58             where TElement : struct
59             where TAggregate : struct
60             where TResult : struct {
Check.SourceAntlr.Runtime.JavaExtensions.EnumerableExtensions.TAggregate61             Check.Source(source);
62 
63             var total = default(TAggregate);
64             long counter = 0;
65             foreach (var element in source) {
66                 total = func(total, element);
67                 ++counter;
68             }
69 
70             if (counter == 0)
InvalidOperationExceptionAntlr.Runtime.JavaExtensions.EnumerableExtensions.TAggregate71                 throw new InvalidOperationException();
72 
73             return result(total, counter);
74         }
75 
Average(IEnumerable<double> source)76         public static double Average(IEnumerable<double> source) {
77             return Average<double, double, double>(source, delegate(double a, double b) { return a + b; }, delegate(double a, long b) { return a / b; });
78         }
79 
80         #endregion
81 
82         #region Contains
83 
Contains(IEnumerable<TSource> source, TSource value)84         public static bool Contains<TSource>(IEnumerable<TSource> source, TSource value) {
85             var collection = source as ICollection<TSource>;
86             if (collection != null)
87                 return collection.Contains(value);
88 
89             return Contains<TSource>(source, value, null);
90         }
91 
Contains(IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)92         public static bool Contains<TSource>(IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer) {
93             Check.Source(source);
94 
95             if (comparer == null)
96                 comparer = EqualityComparer<TSource>.Default;
97 
98             foreach (var element in source)
99                 if (comparer.Equals(element, value))
100                     return true;
101 
102             return false;
103         }
104         #endregion
105 
106         #region DefaultIfEmpty
107 
DefaultIfEmpty(IEnumerable<TSource> source)108         public static IEnumerable<TSource> DefaultIfEmpty<TSource>(IEnumerable<TSource> source) {
109             return DefaultIfEmpty(source, default(TSource));
110         }
111 
DefaultIfEmpty(IEnumerable<TSource> source, TSource defaultValue)112         public static IEnumerable<TSource> DefaultIfEmpty<TSource>(IEnumerable<TSource> source, TSource defaultValue) {
113             Check.Source(source);
114 
115             return CreateDefaultIfEmptyIterator(source, defaultValue);
116         }
117 
CreateDefaultIfEmptyIterator(IEnumerable<TSource> source, TSource defaultValue)118         static IEnumerable<TSource> CreateDefaultIfEmptyIterator<TSource>(IEnumerable<TSource> source, TSource defaultValue) {
119             bool empty = true;
120             foreach (TSource item in source) {
121                 empty = false;
122                 yield return item;
123             }
124 
125             if (empty)
126                 yield return defaultValue;
127         }
128 
129         #endregion
130 
131         #region Max
132 
Max(IEnumerable<int> source)133         public static int Max(IEnumerable<int> source) {
134             Check.Source(source);
135 
136             return Iterate(source, int.MinValue, delegate(int a, int b){return Math.Max(a, b);});
137         }
138 
Iterate(IEnumerable<T> source, U initValue, Func<T, U, U> selector)139         static U Iterate<T, U>(IEnumerable<T> source, U initValue, Func<T, U, U> selector) {
140             bool empty = true;
141             foreach (var element in source) {
142                 initValue = selector(element, initValue);
143                 empty = false;
144             }
145 
146             if (empty)
147                 throw new InvalidOperationException();
148 
149             return initValue;
150         }
151 
152         #endregion
153 
154         #region Min
155 
Min(IEnumerable<int> source)156         public static int Min(IEnumerable<int> source) {
157             Check.Source(source);
158 
159             return Iterate(source, int.MaxValue, delegate(int a, int b) { return Math.Min(a, b); });
160         }
161 
162         #endregion
163 
164         #region Select
165 
Select(IEnumerable<TSource> source, Func<TSource, TResult> selector)166         public static IEnumerable<TResult> Select<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, TResult> selector) {
167             Check.SourceAndSelector(source, selector);
168 
169             return CreateSelectIterator(source, selector);
170         }
171 
CreateSelectIterator(IEnumerable<TSource> source, Func<TSource, TResult> selector)172         static IEnumerable<TResult> CreateSelectIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, TResult> selector) {
173             foreach (var element in source)
174                 yield return selector(element);
175         }
176 
Select(IEnumerable<TSource> source, Func<TSource, int, TResult> selector)177         public static IEnumerable<TResult> Select<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, TResult> selector) {
178             Check.SourceAndSelector(source, selector);
179 
180             return CreateSelectIterator(source, selector);
181         }
182 
CreateSelectIterator(IEnumerable<TSource> source, Func<TSource, int, TResult> selector)183         static IEnumerable<TResult> CreateSelectIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, TResult> selector) {
184             int counter = 0;
185             foreach (TSource element in source) {
186                 yield return selector(element, counter);
187                 counter++;
188             }
189         }
190 
191         #endregion
192 
193         #region SelectMany
194 
SelectMany(IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)195         public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(IEnumerable<TSource> source,
196             Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector) {
197             Check.SourceAndCollectionSelectors(source, collectionSelector, selector);
198 
199             return CreateSelectManyIterator(source, collectionSelector, selector);
200         }
201 
SelectMany(IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)202         public static IEnumerable<TResult> SelectMany<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector) {
203             Check.SourceAndSelector(source, selector);
204 
205             return CreateSelectManyIterator(source, selector);
206         }
207 
CreateSelectManyIterator(IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)208         static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult>(IEnumerable<TSource> source,
209             Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector) {
210             int counter = 0;
211             foreach (TSource element in source)
212                 foreach (TCollection collection in collectionSelector(element, counter++))
213                     yield return selector(element, collection);
214         }
215 
CreateSelectManyIterator(IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)216         static IEnumerable<TResult> CreateSelectManyIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector) {
217             int counter = 0;
218             foreach (TSource element in source) {
219                 foreach (TResult item in selector(element, counter))
220                     yield return item;
221                 counter++;
222             }
223         }
224 
225         #endregion
226 
227         #region Sum
228 
Sum(IEnumerable<int> source)229         public static int Sum(IEnumerable<int> source) {
230             Check.Source(source);
231 
232             return Sum<int, int>(source, delegate(int a, int b) { return checked(a + b); });
233         }
234 
Sum(IEnumerable<TA> source, Func<TR, TA, TR> selector)235         static TR Sum<TA, TR>(IEnumerable<TA> source, Func<TR, TA, TR> selector) {
236             TR total = default(TR);
237             foreach (var element in source) {
238                 total = selector(total, element);
239             }
240 
241             return total;
242         }
243 
244         #endregion
245 
246         #region Take
247 
Take(IEnumerable<TSource> source, int count)248         public static IEnumerable<TSource> Take<TSource>(IEnumerable<TSource> source, int count) {
249             Check.Source(source);
250 
251             return CreateTakeIterator(source, count);
252         }
253 
CreateTakeIterator(IEnumerable<TSource> source, int count)254         static IEnumerable<TSource> CreateTakeIterator<TSource>(IEnumerable<TSource> source, int count) {
255             if (count <= 0)
256                 yield break;
257 
258             int counter = 0;
259             foreach (TSource element in source) {
260                 yield return element;
261 
262                 if (++counter == count)
263                     yield break;
264             }
265         }
266 
267         #endregion
268 
269         #region ToArray
270 
ToArray(IEnumerable<TSource> source)271         public static TSource[] ToArray<TSource>(IEnumerable<TSource> source) {
272             Check.Source(source);
273 
274             var collection = source as ICollection<TSource>;
275             if (collection != null) {
276                 var array = new TSource[collection.Count];
277                 collection.CopyTo(array, 0);
278                 return array;
279             }
280 
281             return new List<TSource>(source).ToArray();
282         }
283 
284         #endregion
285     }
286 }
287