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