2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Threading;
6 // Include Silverlight's managed resources
13 public static class Enumerable
15 public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
16 if (source == null) throw Error.ArgumentNull("source");
17 if (predicate == null) throw Error.ArgumentNull("predicate");
18 if (source is Iterator<TSource>) return ((Iterator<TSource>)source).Where(predicate);
19 if (source is TSource[]) return new WhereArrayIterator<TSource>((TSource[])source, predicate);
20 if (source is List<TSource>) return new WhereListIterator<TSource>((List<TSource>)source, predicate);
21 return new WhereEnumerableIterator<TSource>(source, predicate);
24 public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate) {
25 if (source == null) throw Error.ArgumentNull("source");
26 if (predicate == null) throw Error.ArgumentNull("predicate");
27 return WhereIterator<TSource>(source, predicate);
30 static IEnumerable<TSource> WhereIterator<TSource>(IEnumerable<TSource> source, Func<TSource, int, bool> predicate) {
32 foreach (TSource element in source) {
34 if (predicate(element, index)) yield return element;
38 public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector) {
39 if (source == null) throw Error.ArgumentNull("source");
40 if (selector == null) throw Error.ArgumentNull("selector");
41 if (source is Iterator<TSource>) return ((Iterator<TSource>)source).Select(selector);
42 if (source is TSource[]) return new WhereSelectArrayIterator<TSource, TResult>((TSource[])source, null, selector);
43 if (source is List<TSource>) return new WhereSelectListIterator<TSource, TResult>((List<TSource>)source, null, selector);
44 return new WhereSelectEnumerableIterator<TSource, TResult>(source, null, selector);
47 public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult> selector) {
48 if (source == null) throw Error.ArgumentNull("source");
49 if (selector == null) throw Error.ArgumentNull("selector");
50 return SelectIterator<TSource, TResult>(source, selector);
53 static IEnumerable<TResult> SelectIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, TResult> selector) {
55 foreach (TSource element in source) {
57 yield return selector(element, index);
61 static Func<TSource, bool> CombinePredicates<TSource>(Func<TSource, bool> predicate1, Func<TSource, bool> predicate2) {
62 return x => predicate1(x) && predicate2(x);
65 static Func<TSource, TResult> CombineSelectors<TSource, TMiddle, TResult>(Func<TSource, TMiddle> selector1, Func<TMiddle, TResult> selector2) {
66 return x => selector2(selector1(x));
69 abstract class Iterator<TSource> : IEnumerable<TSource>, IEnumerator<TSource>
73 internal TSource current;
76 threadId = Thread.CurrentThread.ManagedThreadId;
79 public TSource Current {
80 get { return current; }
83 public abstract Iterator<TSource> Clone();
85 public virtual void Dispose() {
86 current = default(TSource);
90 public IEnumerator<TSource> GetEnumerator() {
91 if (threadId == Thread.CurrentThread.ManagedThreadId && state == 0) {
95 Iterator<TSource> duplicate = Clone();
100 public abstract bool MoveNext();
102 public abstract IEnumerable<TResult> Select<TResult>(Func<TSource, TResult> selector);
104 public abstract IEnumerable<TSource> Where(Func<TSource, bool> predicate);
106 object IEnumerator.Current {
107 get { return Current; }
110 IEnumerator IEnumerable.GetEnumerator() {
111 return GetEnumerator();
114 void IEnumerator.Reset() {
115 throw new NotImplementedException();
119 class WhereEnumerableIterator<TSource> : Iterator<TSource>
121 IEnumerable<TSource> source;
122 Func<TSource, bool> predicate;
123 IEnumerator<TSource> enumerator;
125 public WhereEnumerableIterator(IEnumerable<TSource> source, Func<TSource, bool> predicate) {
126 this.source = source;
127 this.predicate = predicate;
130 public override Iterator<TSource> Clone() {
131 return new WhereEnumerableIterator<TSource>(source, predicate);
134 public override void Dispose() {
135 if (enumerator is IDisposable) ((IDisposable)enumerator).Dispose();
140 public override bool MoveNext() {
143 enumerator = source.GetEnumerator();
147 while (enumerator.MoveNext()) {
148 TSource item = enumerator.Current;
149 if (predicate(item)) {
160 public override IEnumerable<TResult> Select<TResult>(Func<TSource, TResult> selector) {
161 return new WhereSelectEnumerableIterator<TSource, TResult>(source, predicate, selector);
164 public override IEnumerable<TSource> Where(Func<TSource, bool> predicate) {
165 return new WhereEnumerableIterator<TSource>(source, CombinePredicates(this.predicate, predicate));
169 class WhereArrayIterator<TSource> : Iterator<TSource>
172 Func<TSource, bool> predicate;
175 public WhereArrayIterator(TSource[] source, Func<TSource, bool> predicate) {
176 this.source = source;
177 this.predicate = predicate;
180 public override Iterator<TSource> Clone() {
181 return new WhereArrayIterator<TSource>(source, predicate);
184 public override bool MoveNext() {
186 while (index < source.Length) {
187 TSource item = source[index];
189 if (predicate(item)) {
199 public override IEnumerable<TResult> Select<TResult>(Func<TSource, TResult> selector) {
200 return new WhereSelectArrayIterator<TSource, TResult>(source, predicate, selector);
203 public override IEnumerable<TSource> Where(Func<TSource, bool> predicate) {
204 return new WhereArrayIterator<TSource>(source, CombinePredicates(this.predicate, predicate));
208 class WhereListIterator<TSource> : Iterator<TSource>
210 List<TSource> source;
211 Func<TSource, bool> predicate;
212 List<TSource>.Enumerator enumerator;
214 public WhereListIterator(List<TSource> source, Func<TSource, bool> predicate) {
215 this.source = source;
216 this.predicate = predicate;
219 public override Iterator<TSource> Clone() {
220 return new WhereListIterator<TSource>(source, predicate);
223 public override bool MoveNext() {
226 enumerator = source.GetEnumerator();
230 while (enumerator.MoveNext()) {
231 TSource item = enumerator.Current;
232 if (predicate(item)) {
243 public override IEnumerable<TResult> Select<TResult>(Func<TSource, TResult> selector) {
244 return new WhereSelectListIterator<TSource, TResult>(source, predicate, selector);
247 public override IEnumerable<TSource> Where(Func<TSource, bool> predicate) {
248 return new WhereListIterator<TSource>(source, CombinePredicates(this.predicate, predicate));
252 class WhereSelectEnumerableIterator<TSource, TResult> : Iterator<TResult>
254 IEnumerable<TSource> source;
255 Func<TSource, bool> predicate;
256 Func<TSource, TResult> selector;
257 IEnumerator<TSource> enumerator;
259 public WhereSelectEnumerableIterator(IEnumerable<TSource> source, Func<TSource, bool> predicate, Func<TSource, TResult> selector) {
260 this.source = source;
261 this.predicate = predicate;
262 this.selector = selector;
265 public override Iterator<TResult> Clone() {
266 return new WhereSelectEnumerableIterator<TSource, TResult>(source, predicate, selector);
269 public override void Dispose() {
270 if (enumerator is IDisposable) ((IDisposable)enumerator).Dispose();
275 public override bool MoveNext() {
278 enumerator = source.GetEnumerator();
282 while (enumerator.MoveNext()) {
283 TSource item = enumerator.Current;
284 if (predicate == null || predicate(item)) {
285 current = selector(item);
295 public override IEnumerable<TResult2> Select<TResult2>(Func<TResult, TResult2> selector) {
296 return new WhereSelectEnumerableIterator<TSource, TResult2>(source, predicate, CombineSelectors(this.selector, selector));
299 public override IEnumerable<TResult> Where(Func<TResult, bool> predicate) {
300 return new WhereEnumerableIterator<TResult>(this, predicate);
304 class WhereSelectArrayIterator<TSource, TResult> : Iterator<TResult>
307 Func<TSource, bool> predicate;
308 Func<TSource, TResult> selector;
311 public WhereSelectArrayIterator(TSource[] source, Func<TSource, bool> predicate, Func<TSource, TResult> selector) {
312 this.source = source;
313 this.predicate = predicate;
314 this.selector = selector;
317 public override Iterator<TResult> Clone() {
318 return new WhereSelectArrayIterator<TSource, TResult>(source, predicate, selector);
321 public override bool MoveNext() {
323 while (index < source.Length) {
324 TSource item = source[index];
326 if (predicate == null || predicate(item)) {
327 current = selector(item);
336 public override IEnumerable<TResult2> Select<TResult2>(Func<TResult, TResult2> selector) {
337 return new WhereSelectArrayIterator<TSource, TResult2>(source, predicate, CombineSelectors(this.selector, selector));
340 public override IEnumerable<TResult> Where(Func<TResult, bool> predicate) {
341 return new WhereEnumerableIterator<TResult>(this, predicate);
345 class WhereSelectListIterator<TSource, TResult> : Iterator<TResult>
347 List<TSource> source;
348 Func<TSource, bool> predicate;
349 Func<TSource, TResult> selector;
350 List<TSource>.Enumerator enumerator;
352 public WhereSelectListIterator(List<TSource> source, Func<TSource, bool> predicate, Func<TSource, TResult> selector) {
353 this.source = source;
354 this.predicate = predicate;
355 this.selector = selector;
358 public override Iterator<TResult> Clone() {
359 return new WhereSelectListIterator<TSource, TResult>(source, predicate, selector);
362 public override bool MoveNext() {
365 enumerator = source.GetEnumerator();
369 while (enumerator.MoveNext()) {
370 TSource item = enumerator.Current;
371 if (predicate == null || predicate(item)) {
372 current = selector(item);
382 public override IEnumerable<TResult2> Select<TResult2>(Func<TResult, TResult2> selector) {
383 return new WhereSelectListIterator<TSource, TResult2>(source, predicate, CombineSelectors(this.selector, selector));
386 public override IEnumerable<TResult> Where(Func<TResult, bool> predicate) {
387 return new WhereEnumerableIterator<TResult>(this, predicate);
391 //public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
392 // if (source == null) throw Error.ArgumentNull("source");
393 // if (predicate == null) throw Error.ArgumentNull("predicate");
394 // return WhereIterator<TSource>(source, predicate);
397 //static IEnumerable<TSource> WhereIterator<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate) {
398 // foreach (TSource element in source) {
399 // if (predicate(element)) yield return element;
403 //public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector) {
404 // if (source == null) throw Error.ArgumentNull("source");
405 // if (selector == null) throw Error.ArgumentNull("selector");
406 // return SelectIterator<TSource, TResult>(source, selector);
409 //static IEnumerable<TResult> SelectIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, TResult> selector) {
410 // foreach (TSource element in source) {
411 // yield return selector(element);
415 public static IEnumerable<TResult> SelectMany<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector) {
416 if (source == null) throw Error.ArgumentNull("source");
417 if (selector == null) throw Error.ArgumentNull("selector");
418 return SelectManyIterator<TSource, TResult>(source, selector);
421 static IEnumerable<TResult> SelectManyIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector) {
422 foreach (TSource element in source) {
423 foreach (TResult subElement in selector(element)) {
424 yield return subElement;
429 public static IEnumerable<TResult> SelectMany<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector) {
430 if (source == null) throw Error.ArgumentNull("source");
431 if (selector == null) throw Error.ArgumentNull("selector");
432 return SelectManyIterator<TSource, TResult>(source, selector);
435 static IEnumerable<TResult> SelectManyIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector) {
437 foreach (TSource element in source) {
439 foreach (TResult subElement in selector(element, index)) {
440 yield return subElement;
444 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
446 if (source == null) throw Error.ArgumentNull("source");
447 if (collectionSelector == null) throw Error.ArgumentNull("collectionSelector");
448 if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
449 return SelectManyIterator<TSource, TCollection, TResult>(source, collectionSelector, resultSelector);
452 static IEnumerable<TResult> SelectManyIterator<TSource, TCollection, TResult>(IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector){
454 foreach (TSource element in source){
456 foreach (TCollection subElement in collectionSelector(element, index)){
457 yield return resultSelector(element, subElement);
462 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector) {
463 if (source == null) throw Error.ArgumentNull("source");
464 if (collectionSelector == null) throw Error.ArgumentNull("collectionSelector");
465 if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
466 return SelectManyIterator<TSource, TCollection, TResult>(source, collectionSelector, resultSelector);
469 static IEnumerable<TResult> SelectManyIterator<TSource, TCollection, TResult>(IEnumerable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector) {
470 foreach (TSource element in source) {
471 foreach (TCollection subElement in collectionSelector(element)) {
472 yield return resultSelector(element, subElement);
477 public static IEnumerable<TSource> Take<TSource>(this IEnumerable<TSource> source, int count) {
478 if (source == null) throw Error.ArgumentNull("source");
479 return TakeIterator<TSource>(source, count);
482 static IEnumerable<TSource> TakeIterator<TSource>(IEnumerable<TSource> source, int count) {
484 foreach (TSource element in source) {
485 yield return element;
486 if (--count == 0) break;
491 public static IEnumerable<TSource> TakeWhile<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
492 if (source == null) throw Error.ArgumentNull("source");
493 if (predicate == null) throw Error.ArgumentNull("predicate");
494 return TakeWhileIterator<TSource>(source, predicate);
497 static IEnumerable<TSource> TakeWhileIterator<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate) {
498 foreach (TSource element in source) {
499 if (!predicate(element)) break;
500 yield return element;
504 public static IEnumerable<TSource> TakeWhile<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate) {
505 if (source == null) throw Error.ArgumentNull("source");
506 if (predicate == null) throw Error.ArgumentNull("predicate");
507 return TakeWhileIterator<TSource>(source, predicate);
510 static IEnumerable<TSource> TakeWhileIterator<TSource>(IEnumerable<TSource> source, Func<TSource, int, bool> predicate) {
512 foreach (TSource element in source) {
514 if (!predicate(element, index)) break;
515 yield return element;
519 public static IEnumerable<TSource> Skip<TSource>(this IEnumerable<TSource> source, int count) {
520 if (source == null) throw Error.ArgumentNull("source");
521 return SkipIterator<TSource>(source, count);
524 static IEnumerable<TSource> SkipIterator<TSource>(IEnumerable<TSource> source, int count) {
525 using (IEnumerator<TSource> e = source.GetEnumerator()) {
526 while (count > 0 && e.MoveNext()) count--;
528 while (e.MoveNext()) yield return e.Current;
533 public static IEnumerable<TSource> SkipWhile<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
534 if (source == null) throw Error.ArgumentNull("source");
535 if (predicate == null) throw Error.ArgumentNull("predicate");
536 return SkipWhileIterator<TSource>(source, predicate);
539 static IEnumerable<TSource> SkipWhileIterator<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate) {
540 bool yielding = false;
541 foreach (TSource element in source) {
542 if (!yielding && !predicate(element)) yielding = true;
543 if (yielding) yield return element;
547 public static IEnumerable<TSource> SkipWhile<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate) {
548 if (source == null) throw Error.ArgumentNull("source");
549 if (predicate == null) throw Error.ArgumentNull("predicate");
550 return SkipWhileIterator<TSource>(source, predicate);
553 static IEnumerable<TSource> SkipWhileIterator<TSource>(IEnumerable<TSource> source, Func<TSource, int, bool> predicate) {
555 bool yielding = false;
556 foreach (TSource element in source) {
558 if (!yielding && !predicate(element, index)) yielding = true;
559 if (yielding) yield return element;
563 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector) {
564 if (outer == null) throw Error.ArgumentNull("outer");
565 if (inner == null) throw Error.ArgumentNull("inner");
566 if (outerKeySelector == null) throw Error.ArgumentNull("outerKeySelector");
567 if (innerKeySelector == null) throw Error.ArgumentNull("innerKeySelector");
568 if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
569 return JoinIterator<TOuter, TInner, TKey, TResult>(outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
572 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer) {
573 if (outer == null) throw Error.ArgumentNull("outer");
574 if (inner == null) throw Error.ArgumentNull("inner");
575 if (outerKeySelector == null) throw Error.ArgumentNull("outerKeySelector");
576 if (innerKeySelector == null) throw Error.ArgumentNull("innerKeySelector");
577 if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
578 return JoinIterator<TOuter, TInner, TKey, TResult>(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
581 static IEnumerable<TResult> JoinIterator<TOuter, TInner, TKey, TResult>(IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer) {
582 Lookup<TKey, TInner> lookup = Lookup<TKey, TInner>.CreateForJoin(inner, innerKeySelector, comparer);
583 foreach (TOuter item in outer) {
584 Lookup<TKey, TInner>.Grouping g = lookup.GetGrouping(outerKeySelector(item), false);
586 for (int i = 0; i < g.count; i++) {
587 yield return resultSelector(item, g.elements[i]);
593 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector) {
594 if (outer == null) throw Error.ArgumentNull("outer");
595 if (inner == null) throw Error.ArgumentNull("inner");
596 if (outerKeySelector == null) throw Error.ArgumentNull("outerKeySelector");
597 if (innerKeySelector == null) throw Error.ArgumentNull("innerKeySelector");
598 if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
599 return GroupJoinIterator<TOuter, TInner, TKey, TResult>(outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);
602 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector, IEqualityComparer<TKey> comparer) {
603 if (outer == null) throw Error.ArgumentNull("outer");
604 if (inner == null) throw Error.ArgumentNull("inner");
605 if (outerKeySelector == null) throw Error.ArgumentNull("outerKeySelector");
606 if (innerKeySelector == null) throw Error.ArgumentNull("innerKeySelector");
607 if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
608 return GroupJoinIterator<TOuter, TInner, TKey, TResult>(outer, inner, outerKeySelector, innerKeySelector, resultSelector, comparer);
611 static IEnumerable<TResult> GroupJoinIterator<TOuter, TInner, TKey, TResult>(IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector, IEqualityComparer<TKey> comparer) {
612 Lookup<TKey, TInner> lookup = Lookup<TKey, TInner>.CreateForJoin(inner, innerKeySelector, comparer);
613 foreach (TOuter item in outer) {
614 yield return resultSelector(item, lookup[outerKeySelector(item)]);
618 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) {
619 return new OrderedEnumerable<TSource, TKey>(source, keySelector, null, false);
622 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer) {
623 return new OrderedEnumerable<TSource, TKey>(source, keySelector, comparer, false);
626 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) {
627 return new OrderedEnumerable<TSource, TKey>(source, keySelector, null, true);
630 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer) {
631 return new OrderedEnumerable<TSource, TKey>(source, keySelector, comparer, true);
634 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector) {
635 if (source == null) throw Error.ArgumentNull("source");
636 return source.CreateOrderedEnumerable<TKey>(keySelector, null, false);
639 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer) {
640 if (source == null) throw Error.ArgumentNull("source");
641 return source.CreateOrderedEnumerable<TKey>(keySelector, comparer, false);
644 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>(this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector) {
645 if (source == null) throw Error.ArgumentNull("source");
646 return source.CreateOrderedEnumerable<TKey>(keySelector, null, true);
649 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>(this IOrderedEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer) {
650 if (source == null) throw Error.ArgumentNull("source");
651 return source.CreateOrderedEnumerable<TKey>(keySelector, comparer, true);
654 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) {
655 return new GroupedEnumerable<TSource, TKey, TSource>(source, keySelector, IdentityFunction<TSource>.Instance, null);
658 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer) {
659 return new GroupedEnumerable<TSource, TKey, TSource>(source, keySelector, IdentityFunction<TSource>.Instance, comparer);
662 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector) {
663 return new GroupedEnumerable<TSource, TKey, TElement>(source, keySelector, elementSelector, null);
666 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer) {
667 return new GroupedEnumerable<TSource, TKey, TElement>(source, keySelector, elementSelector, comparer);
670 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TKey, IEnumerable<TSource>, TResult> resultSelector){
671 return new GroupedEnumerable<TSource, TKey, TSource, TResult>(source, keySelector, IdentityFunction<TSource>.Instance, resultSelector, null);
674 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<TKey, IEnumerable<TElement>, TResult> resultSelector){
675 return new GroupedEnumerable<TSource, TKey, TElement, TResult>(source, keySelector, elementSelector, resultSelector, null);
678 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TKey, IEnumerable<TSource>, TResult> resultSelector, IEqualityComparer<TKey> comparer){
679 return new GroupedEnumerable<TSource, TKey, TSource, TResult>(source, keySelector, IdentityFunction<TSource>.Instance, resultSelector, comparer);
682 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<TKey, IEnumerable<TElement>, TResult> resultSelector, IEqualityComparer<TKey> comparer){
683 return new GroupedEnumerable<TSource, TKey, TElement, TResult>(source, keySelector, elementSelector, resultSelector, comparer);
686 public static IEnumerable<TSource> Concat<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second) {
687 if (first == null) throw Error.ArgumentNull("first");
688 if (second == null) throw Error.ArgumentNull("second");
689 return ConcatIterator<TSource>(first, second);
692 static IEnumerable<TSource> ConcatIterator<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second) {
693 foreach (TSource element in first) yield return element;
694 foreach (TSource element in second) yield return element;
697 public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector) {
698 if (first == null) throw Error.ArgumentNull("first");
699 if (second == null) throw Error.ArgumentNull("second");
700 if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
701 return ZipIterator(first, second, resultSelector);
704 static IEnumerable<TResult> ZipIterator<TFirst, TSecond, TResult>(IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector) {
705 using (IEnumerator<TFirst> e1 = first.GetEnumerator())
706 using (IEnumerator<TSecond> e2 = second.GetEnumerator())
707 while (e1.MoveNext() && e2.MoveNext())
708 yield return resultSelector(e1.Current, e2.Current);
712 public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source) {
713 if (source == null) throw Error.ArgumentNull("source");
714 return DistinctIterator<TSource>(source, null);
717 public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer) {
718 if (source == null) throw Error.ArgumentNull("source");
719 return DistinctIterator<TSource>(source, comparer);
722 static IEnumerable<TSource> DistinctIterator<TSource>(IEnumerable<TSource> source, IEqualityComparer<TSource> comparer) {
723 Set<TSource> set = new Set<TSource>(comparer);
724 foreach (TSource element in source)
725 if (set.Add(element)) yield return element;
728 public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second) {
729 if (first == null) throw Error.ArgumentNull("first");
730 if (second == null) throw Error.ArgumentNull("second");
731 return UnionIterator<TSource>(first, second, null);
734 public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
736 if (first == null) throw Error.ArgumentNull("first");
737 if (second == null) throw Error.ArgumentNull("second");
738 return UnionIterator<TSource>(first, second, comparer);
741 static IEnumerable<TSource> UnionIterator<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
743 Set<TSource> set = new Set<TSource>(comparer);
744 foreach (TSource element in first)
745 if (set.Add(element)) yield return element;
746 foreach (TSource element in second)
747 if (set.Add(element)) yield return element;
750 public static IEnumerable<TSource> Intersect<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second) {
751 if (first == null) throw Error.ArgumentNull("first");
752 if (second == null) throw Error.ArgumentNull("second");
753 return IntersectIterator<TSource>(first, second, null);
756 public static IEnumerable<TSource> Intersect<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
758 if (first == null) throw Error.ArgumentNull("first");
759 if (second == null) throw Error.ArgumentNull("second");
760 return IntersectIterator<TSource>(first, second, comparer);
763 static IEnumerable<TSource> IntersectIterator<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
765 Set<TSource> set = new Set<TSource>(comparer);
766 foreach (TSource element in second) set.Add(element);
767 foreach (TSource element in first)
768 if (set.Remove(element)) yield return element;
771 public static IEnumerable<TSource> Except<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second)
773 if (first == null) throw Error.ArgumentNull("first");
774 if (second == null) throw Error.ArgumentNull("second");
775 return ExceptIterator<TSource>(first, second, null);
778 public static IEnumerable<TSource> Except<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
780 if (first == null) throw Error.ArgumentNull("first");
781 if (second == null) throw Error.ArgumentNull("second");
782 return ExceptIterator<TSource>(first, second, comparer);
785 static IEnumerable<TSource> ExceptIterator<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer) {
786 Set<TSource> set = new Set<TSource>(comparer);
787 foreach (TSource element in second) set.Add(element);
788 foreach (TSource element in first)
789 if (set.Add(element)) yield return element;
792 public static IEnumerable<TSource> Reverse<TSource>(this IEnumerable<TSource> source) {
793 if (source == null) throw Error.ArgumentNull("source");
794 return ReverseIterator<TSource>(source);
797 static IEnumerable<TSource> ReverseIterator<TSource>(IEnumerable<TSource> source) {
798 Buffer<TSource> buffer = new Buffer<TSource>(source);
799 for (int i = buffer.count - 1; i >= 0; i--) yield return buffer.items[i];
802 public static bool SequenceEqual<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second) {
803 return SequenceEqual<TSource>(first, second, null);
806 public static bool SequenceEqual<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
808 if (comparer == null) comparer = EqualityComparer<TSource>.Default;
809 if (first == null) throw Error.ArgumentNull("first");
810 if (second == null) throw Error.ArgumentNull("second");
811 using (IEnumerator<TSource> e1 = first.GetEnumerator())
812 using (IEnumerator<TSource> e2 = second.GetEnumerator())
814 while (e1.MoveNext())
816 if (!(e2.MoveNext() && comparer.Equals(e1.Current, e2.Current))) return false;
818 if (e2.MoveNext()) return false;
823 public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source)
828 public static TSource[] ToArray<TSource>(this IEnumerable<TSource> source) {
829 if (source == null) throw Error.ArgumentNull("source");
830 return new Buffer<TSource>(source).ToArray();
833 public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source) {
834 if (source == null) throw Error.ArgumentNull("source");
835 return new List<TSource>(source);
838 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) {
839 return ToDictionary<TSource, TKey, TSource>(source, keySelector, IdentityFunction<TSource>.Instance, null);
842 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer) {
843 return ToDictionary<TSource, TKey, TSource>(source, keySelector, IdentityFunction<TSource>.Instance, comparer);
846 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector) {
847 return ToDictionary<TSource, TKey, TElement>(source, keySelector, elementSelector, null);
850 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer) {
851 if (source == null) throw Error.ArgumentNull("source");
852 if (keySelector == null) throw Error.ArgumentNull("keySelector");
853 if (elementSelector == null) throw Error.ArgumentNull("elementSelector");
854 Dictionary<TKey, TElement> d = new Dictionary<TKey, TElement>(comparer);
855 foreach (TSource element in source) d.Add(keySelector(element), elementSelector(element));
859 public static ILookup<TKey, TSource> ToLookup<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) {
860 return Lookup<TKey, TSource>.Create(source, keySelector, IdentityFunction<TSource>.Instance, null);
863 public static ILookup<TKey, TSource> ToLookup<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer) {
864 return Lookup<TKey, TSource>.Create(source, keySelector, IdentityFunction<TSource>.Instance, comparer);
867 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector) {
868 return Lookup<TKey, TElement>.Create(source, keySelector, elementSelector, null);
871 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer) {
872 return Lookup<TKey, TElement>.Create(source, keySelector, elementSelector, comparer);
875 public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source) {
876 return DefaultIfEmpty(source, default(TSource));
879 public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source, TSource defaultValue) {
880 if (source == null) throw Error.ArgumentNull("source");
881 return DefaultIfEmptyIterator<TSource>(source, defaultValue);
884 static IEnumerable<TSource> DefaultIfEmptyIterator<TSource>(IEnumerable<TSource> source, TSource defaultValue) {
885 using (IEnumerator<TSource> e = source.GetEnumerator()) {
888 yield return e.Current;
889 } while (e.MoveNext());
892 yield return defaultValue;
897 public static IEnumerable<TResult> OfType<TResult>(this IEnumerable source) {
898 if (source == null) throw Error.ArgumentNull("source");
899 return OfTypeIterator<TResult>(source);
902 static IEnumerable<TResult> OfTypeIterator<TResult>(IEnumerable source) {
903 foreach (object obj in source) {
904 if (obj is TResult) yield return (TResult)obj;
908 public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source) {
909 IEnumerable<TResult> typedSource = source as IEnumerable<TResult>;
910 if (typedSource != null) return typedSource;
911 if (source == null) throw Error.ArgumentNull("source");
912 return CastIterator<TResult>(source);
915 static IEnumerable<TResult> CastIterator<TResult>(IEnumerable source) {
916 foreach (object obj in source) yield return (TResult)obj;
919 public static TSource First<TSource>(this IEnumerable<TSource> source) {
920 if (source == null) throw Error.ArgumentNull("source");
921 IList<TSource> list = source as IList<TSource>;
923 if (list.Count > 0) return list[0];
926 using (IEnumerator<TSource> e = source.GetEnumerator()) {
927 if (e.MoveNext()) return e.Current;
930 throw Error.NoElements();
933 public static TSource First<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
934 if (source == null) throw Error.ArgumentNull("source");
935 if (predicate == null) throw Error.ArgumentNull("predicate");
936 foreach (TSource element in source) {
937 if (predicate(element)) return element;
939 throw Error.NoMatch();
942 public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source) {
943 if (source == null) throw Error.ArgumentNull("source");
944 IList<TSource> list = source as IList<TSource>;
946 if (list.Count > 0) return list[0];
949 using (IEnumerator<TSource> e = source.GetEnumerator()) {
950 if (e.MoveNext()) return e.Current;
953 return default(TSource);
956 public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
957 if (source == null) throw Error.ArgumentNull("source");
958 if (predicate == null) throw Error.ArgumentNull("predicate");
959 foreach (TSource element in source) {
960 if (predicate(element)) return element;
962 return default(TSource);
965 public static TSource Last<TSource>(this IEnumerable<TSource> source) {
966 if (source == null) throw Error.ArgumentNull("source");
967 IList<TSource> list = source as IList<TSource>;
969 int count = list.Count;
970 if (count > 0) return list[count - 1];
973 using (IEnumerator<TSource> e = source.GetEnumerator()) {
978 } while (e.MoveNext());
983 throw Error.NoElements();
986 public static TSource Last<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
987 if (source == null) throw Error.ArgumentNull("source");
988 if (predicate == null) throw Error.ArgumentNull("predicate");
989 TSource result = default(TSource);
991 foreach (TSource element in source) {
992 if (predicate(element)) {
997 if (found) return result;
998 throw Error.NoMatch();
1001 public static TSource LastOrDefault<TSource>(this IEnumerable<TSource> source) {
1002 if (source == null) throw Error.ArgumentNull("source");
1003 IList<TSource> list = source as IList<TSource>;
1005 int count = list.Count;
1006 if (count > 0) return list[count - 1];
1009 using (IEnumerator<TSource> e = source.GetEnumerator()) {
1014 } while (e.MoveNext());
1019 return default(TSource);
1022 public static TSource LastOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
1023 if (source == null) throw Error.ArgumentNull("source");
1024 if (predicate == null) throw Error.ArgumentNull("predicate");
1025 TSource result = default(TSource);
1026 foreach (TSource element in source) {
1027 if (predicate(element)) {
1034 public static TSource Single<TSource>(this IEnumerable<TSource> source) {
1035 if (source == null) throw Error.ArgumentNull("source");
1036 IList<TSource> list = source as IList<TSource>;
1038 switch (list.Count) {
1039 case 0: throw Error.NoElements();
1040 case 1: return list[0];
1044 using (IEnumerator<TSource> e = source.GetEnumerator()) {
1045 if (!e.MoveNext()) throw Error.NoElements();
1046 TSource result = e.Current;
1047 if (!e.MoveNext()) return result;
1050 throw Error.MoreThanOneElement();
1053 public static TSource Single<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
1054 if (source == null) throw Error.ArgumentNull("source");
1055 if (predicate == null) throw Error.ArgumentNull("predicate");
1056 TSource result = default(TSource);
1058 foreach (TSource element in source) {
1059 if (predicate(element)) {
1061 checked { count++; }
1065 case 0: throw Error.NoMatch();
1066 case 1: return result;
1068 throw Error.MoreThanOneMatch();
1071 public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source) {
1072 if (source == null) throw Error.ArgumentNull("source");
1073 IList<TSource> list = source as IList<TSource>;
1075 switch (list.Count) {
1076 case 0: return default(TSource);
1077 case 1: return list[0];
1081 using (IEnumerator<TSource> e = source.GetEnumerator()) {
1082 if (!e.MoveNext()) return default(TSource);
1083 TSource result = e.Current;
1084 if (!e.MoveNext()) return result;
1087 throw Error.MoreThanOneElement();
1090 public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
1091 if (source == null) throw Error.ArgumentNull("source");
1092 if (predicate == null) throw Error.ArgumentNull("predicate");
1093 TSource result = default(TSource);
1095 foreach (TSource element in source) {
1096 if (predicate(element)) {
1098 checked { count++; }
1102 case 0: return default(TSource);
1103 case 1: return result;
1105 throw Error.MoreThanOneMatch();
1108 public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index) {
1109 if (source == null) throw Error.ArgumentNull("source");
1110 IList<TSource> list = source as IList<TSource>;
1111 if (list != null) return list[index];
1112 if (index < 0) throw Error.ArgumentOutOfRange("index");
1113 using (IEnumerator<TSource> e = source.GetEnumerator()) {
1115 if (!e.MoveNext()) throw Error.ArgumentOutOfRange("index");
1116 if (index == 0) return e.Current;
1122 public static TSource ElementAtOrDefault<TSource>(this IEnumerable<TSource> source, int index) {
1123 if (source == null) throw Error.ArgumentNull("source");
1125 IList<TSource> list = source as IList<TSource>;
1127 if (index < list.Count) return list[index];
1130 using (IEnumerator<TSource> e = source.GetEnumerator()) {
1132 if (!e.MoveNext()) break;
1133 if (index == 0) return e.Current;
1139 return default(TSource);
1142 public static IEnumerable<int> Range(int start, int count) {
1143 long max = ((long)start) + count - 1;
1144 if (count < 0 || max > Int32.MaxValue) throw Error.ArgumentOutOfRange("count");
1145 return RangeIterator(start, count);
1148 static IEnumerable<int> RangeIterator(int start, int count) {
1149 for (int i = 0; i < count; i++) yield return start + i;
1152 public static IEnumerable<TResult> Repeat<TResult>(TResult element, int count) {
1153 if (count < 0) throw Error.ArgumentOutOfRange("count");
1154 return RepeatIterator<TResult>(element, count);
1157 static IEnumerable<TResult> RepeatIterator<TResult>(TResult element, int count) {
1158 for (int i = 0; i < count; i++) yield return element;
1161 public static IEnumerable<TResult> Empty<TResult>() {
1162 return EmptyEnumerable<TResult>.Instance;
1165 public static bool Any<TSource>(this IEnumerable<TSource> source) {
1166 if (source == null) throw Error.ArgumentNull("source");
1167 using (IEnumerator<TSource> e = source.GetEnumerator()) {
1168 if (e.MoveNext()) return true;
1173 public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
1174 if (source == null) throw Error.ArgumentNull("source");
1175 if (predicate == null) throw Error.ArgumentNull("predicate");
1176 foreach (TSource element in source) {
1177 if (predicate(element)) return true;
1182 public static bool All<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
1183 if (source == null) throw Error.ArgumentNull("source");
1184 if (predicate == null) throw Error.ArgumentNull("predicate");
1185 foreach (TSource element in source) {
1186 if (!predicate(element)) return false;
1191 public static int Count<TSource>(this IEnumerable<TSource> source) {
1192 if (source == null) throw Error.ArgumentNull("source");
1193 ICollection<TSource> collectionoft = source as ICollection<TSource>;
1194 if (collectionoft != null) return collectionoft.Count;
1195 ICollection collection = source as ICollection;
1196 if (collection != null) return collection.Count;
1198 using (IEnumerator<TSource> e = source.GetEnumerator()) {
1200 while (e.MoveNext()) count++;
1206 public static int Count<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
1207 if (source == null) throw Error.ArgumentNull("source");
1208 if (predicate == null) throw Error.ArgumentNull("predicate");
1210 foreach (TSource element in source) {
1212 if (predicate(element)) count++;
1218 public static long LongCount<TSource>(this IEnumerable<TSource> source) {
1219 if (source == null) throw Error.ArgumentNull("source");
1221 using (IEnumerator<TSource> e = source.GetEnumerator()) {
1223 while (e.MoveNext()) count++;
1229 public static long LongCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
1230 if (source == null) throw Error.ArgumentNull("source");
1231 if (predicate == null) throw Error.ArgumentNull("predicate");
1233 foreach (TSource element in source) {
1235 if (predicate(element)) count++;
1241 public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value) {
1242 ICollection<TSource> collection = source as ICollection<TSource>;
1243 if (collection != null) return collection.Contains(value);
1244 return Contains<TSource>(source, value, null);
1247 public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
1249 if (comparer == null) comparer = EqualityComparer<TSource>.Default;
1250 if (source == null) throw Error.ArgumentNull("source");
1251 foreach (TSource element in source)
1252 if (comparer.Equals(element, value)) return true;
1256 public static TSource Aggregate<TSource>(this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func)
1258 if (source == null) throw Error.ArgumentNull("source");
1259 if (func == null) throw Error.ArgumentNull("func");
1260 using (IEnumerator<TSource> e = source.GetEnumerator()) {
1261 if (!e.MoveNext()) throw Error.NoElements();
1262 TSource result = e.Current;
1263 while (e.MoveNext()) result = func(result, e.Current);
1268 public static TAccumulate Aggregate<TSource, TAccumulate>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func) {
1269 if (source == null) throw Error.ArgumentNull("source");
1270 if (func == null) throw Error.ArgumentNull("func");
1271 TAccumulate result = seed;
1272 foreach (TSource element in source) result = func(result, element);
1276 public static TResult Aggregate<TSource, TAccumulate, TResult>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, Func<TAccumulate, TResult> resultSelector) {
1277 if (source == null) throw Error.ArgumentNull("source");
1278 if (func == null) throw Error.ArgumentNull("func");
1279 if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
1280 TAccumulate result = seed;
1281 foreach (TSource element in source) result = func(result, element);
1282 return resultSelector(result);
1285 public static int Sum(this IEnumerable<int> source) {
1286 if (source == null) throw Error.ArgumentNull("source");
1289 foreach (int v in source) sum += v;
1294 public static int? Sum(this IEnumerable<int?> source) {
1295 if (source == null) throw Error.ArgumentNull("source");
1298 foreach (int? v in source) {
1299 if (v != null) sum += v.GetValueOrDefault();
1305 public static long Sum(this IEnumerable<long> source) {
1306 if (source == null) throw Error.ArgumentNull("source");
1309 foreach (long v in source) sum += v;
1314 public static long? Sum(this IEnumerable<long?> source) {
1315 if (source == null) throw Error.ArgumentNull("source");
1318 foreach (long? v in source) {
1319 if (v != null) sum += v.GetValueOrDefault();
1325 public static float Sum(this IEnumerable<float> source) {
1326 if (source == null) throw Error.ArgumentNull("source");
1328 foreach (float v in source) sum += v;
1332 public static float? Sum(this IEnumerable<float?> source) {
1333 if (source == null) throw Error.ArgumentNull("source");
1335 foreach (float? v in source) {
1336 if (v != null) sum += v.GetValueOrDefault();
1341 public static double Sum(this IEnumerable<double> source) {
1342 if (source == null) throw Error.ArgumentNull("source");
1344 foreach (double v in source) sum += v;
1348 public static double? Sum(this IEnumerable<double?> source) {
1349 if (source == null) throw Error.ArgumentNull("source");
1351 foreach (double? v in source) {
1352 if (v != null) sum += v.GetValueOrDefault();
1357 public static decimal Sum(this IEnumerable<decimal> source) {
1358 if (source == null) throw Error.ArgumentNull("source");
1360 foreach (decimal v in source) sum += v;
1364 public static decimal? Sum(this IEnumerable<decimal?> source) {
1365 if (source == null) throw Error.ArgumentNull("source");
1367 foreach (decimal? v in source) {
1368 if (v != null) sum += v.GetValueOrDefault();
1373 public static int Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector) {
1374 return Enumerable.Sum(Enumerable.Select(source, selector));
1377 public static int? Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, int?> selector) {
1378 return Enumerable.Sum(Enumerable.Select(source, selector));
1381 public static long Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, long> selector) {
1382 return Enumerable.Sum(Enumerable.Select(source, selector));
1385 public static long? Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, long?> selector) {
1386 return Enumerable.Sum(Enumerable.Select(source, selector));
1389 public static float Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, float> selector) {
1390 return Enumerable.Sum(Enumerable.Select(source, selector));
1393 public static float? Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, float?> selector) {
1394 return Enumerable.Sum(Enumerable.Select(source, selector));
1397 public static double Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, double> selector) {
1398 return Enumerable.Sum(Enumerable.Select(source, selector));
1401 public static double? Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, double?> selector) {
1402 return Enumerable.Sum(Enumerable.Select(source, selector));
1405 public static decimal Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal> selector) {
1406 return Enumerable.Sum(Enumerable.Select(source, selector));
1409 public static decimal? Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal?> selector) {
1410 return Enumerable.Sum(Enumerable.Select(source, selector));
1413 public static int Min(this IEnumerable<int> source) {
1414 if (source == null) throw Error.ArgumentNull("source");
1416 bool hasValue = false;
1417 foreach (int x in source) {
1419 if (x < value) value = x;
1426 if (hasValue) return value;
1427 throw Error.NoElements();
1430 public static int? Min(this IEnumerable<int?> source) {
1431 if (source == null) throw Error.ArgumentNull("source");
1433 foreach (int? x in source) {
1434 if (value == null || x < value)
1440 public static long Min(this IEnumerable<long> source) {
1441 if (source == null) throw Error.ArgumentNull("source");
1443 bool hasValue = false;
1444 foreach (long x in source) {
1446 if (x < value) value = x;
1453 if (hasValue) return value;
1454 throw Error.NoElements();
1457 public static long? Min(this IEnumerable<long?> source) {
1458 if (source == null) throw Error.ArgumentNull("source");
1460 foreach (long? x in source) {
1461 if (value == null || x < value) value = x;
1466 public static float Min(this IEnumerable<float> source) {
1467 if (source == null) throw Error.ArgumentNull("source");
1469 bool hasValue = false;
1470 foreach (float x in source) {
1472 // Normally NaN < anything is false, as is anything < NaN
1473 // However, this leads to some irksome outcomes in Min and Max.
1474 // If we use those semantics then Min(NaN, 5.0) is NaN, but
1475 // Min(5.0, NaN) is 5.0! To fix this, we impose a total
1476 // ordering where NaN is smaller than every value, including
1477 // negative infinity.
1478 if (x < value || System.Single.IsNaN(x)) value = x;
1485 if (hasValue) return value;
1486 throw Error.NoElements();
1489 public static float? Min(this IEnumerable<float?> source) {
1490 if (source == null) throw Error.ArgumentNull("source");
1491 float? value = null;
1492 foreach (float? x in source) {
1493 if (x == null) continue;
1494 if (value == null || x < value || System.Single.IsNaN((float)x)) value = x;
1499 public static double Min(this IEnumerable<double> source) {
1500 if (source == null) throw Error.ArgumentNull("source");
1502 bool hasValue = false;
1503 foreach (double x in source) {
1505 if (x < value || System.Double.IsNaN(x)) value = x;
1512 if (hasValue) return value;
1513 throw Error.NoElements();
1516 public static double? Min(this IEnumerable<double?> source) {
1517 if (source == null) throw Error.ArgumentNull("source");
1518 double? value = null;
1519 foreach (double? x in source) {
1520 if (x == null) continue;
1521 if (value == null || x < value || System.Double.IsNaN((double)x)) value = x;
1526 public static decimal Min(this IEnumerable<decimal> source) {
1527 if (source == null) throw Error.ArgumentNull("source");
1529 bool hasValue = false;
1530 foreach (decimal x in source) {
1532 if (x < value) value = x;
1539 if (hasValue) return value;
1540 throw Error.NoElements();
1543 public static decimal? Min(this IEnumerable<decimal?> source) {
1544 if (source == null) throw Error.ArgumentNull("source");
1545 decimal? value = null;
1546 foreach (decimal? x in source) {
1547 if (value == null || x < value) value = x;
1552 public static TSource Min<TSource>(this IEnumerable<TSource> source) {
1553 if (source == null) throw Error.ArgumentNull("source");
1554 Comparer<TSource> comparer = Comparer<TSource>.Default;
1555 TSource value = default(TSource);
1556 if (value == null) {
1557 foreach (TSource x in source) {
1558 if (x != null && (value == null || comparer.Compare(x, value) < 0))
1564 bool hasValue = false;
1565 foreach (TSource x in source) {
1567 if (comparer.Compare(x, value) < 0)
1575 if (hasValue) return value;
1576 throw Error.NoElements();
1580 public static int Min<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector) {
1581 return Enumerable.Min(Enumerable.Select(source, selector));
1584 public static int? Min<TSource>(this IEnumerable<TSource> source, Func<TSource, int?> selector) {
1585 return Enumerable.Min(Enumerable.Select(source, selector));
1588 public static long Min<TSource>(this IEnumerable<TSource> source, Func<TSource, long> selector) {
1589 return Enumerable.Min(Enumerable.Select(source, selector));
1592 public static long? Min<TSource>(this IEnumerable<TSource> source, Func<TSource, long?> selector) {
1593 return Enumerable.Min(Enumerable.Select(source, selector));
1596 public static float Min<TSource>(this IEnumerable<TSource> source, Func<TSource, float> selector) {
1597 return Enumerable.Min(Enumerable.Select(source, selector));
1600 public static float? Min<TSource>(this IEnumerable<TSource> source, Func<TSource, float?> selector) {
1601 return Enumerable.Min(Enumerable.Select(source, selector));
1604 public static double Min<TSource>(this IEnumerable<TSource> source, Func<TSource, double> selector) {
1605 return Enumerable.Min(Enumerable.Select(source, selector));
1608 public static double? Min<TSource>(this IEnumerable<TSource> source, Func<TSource, double?> selector) {
1609 return Enumerable.Min(Enumerable.Select(source, selector));
1612 public static decimal Min<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal> selector) {
1613 return Enumerable.Min(Enumerable.Select(source, selector));
1616 public static decimal? Min<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal?> selector) {
1617 return Enumerable.Min(Enumerable.Select(source, selector));
1620 public static TResult Min<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector) {
1621 return Enumerable.Min(Enumerable.Select(source, selector));
1624 public static int Max(this IEnumerable<int> source) {
1625 if (source == null) throw Error.ArgumentNull("source");
1627 bool hasValue = false;
1628 foreach (int x in source) {
1630 if (x > value) value = x;
1637 if (hasValue) return value;
1638 throw Error.NoElements();
1641 public static int? Max(this IEnumerable<int?> source) {
1642 if (source == null) throw Error.ArgumentNull("source");
1644 foreach (int? x in source) {
1645 if (value == null || x > value) value = x;
1650 public static long Max(this IEnumerable<long> source) {
1651 if (source == null) throw Error.ArgumentNull("source");
1653 bool hasValue = false;
1654 foreach (long x in source) {
1656 if (x > value) value = x;
1663 if (hasValue) return value;
1664 throw Error.NoElements();
1667 public static long? Max(this IEnumerable<long?> source) {
1668 if (source == null) throw Error.ArgumentNull("source");
1670 foreach (long? x in source) {
1671 if (value == null || x > value) value = x;
1676 public static double Max(this IEnumerable<double> source) {
1677 if (source == null) throw Error.ArgumentNull("source");
1679 bool hasValue = false;
1680 foreach (double x in source) {
1682 if (x > value || System.Double.IsNaN(value)) value = x;
1689 if (hasValue) return value;
1690 throw Error.NoElements();
1693 public static double? Max(this IEnumerable<double?> source) {
1694 if (source == null) throw Error.ArgumentNull("source");
1695 double? value = null;
1696 foreach (double? x in source) {
1697 if (x == null) continue;
1698 if (value == null || x > value || System.Double.IsNaN((double)value)) value = x;
1703 public static float Max(this IEnumerable<float> source) {
1704 if (source == null) throw Error.ArgumentNull("source");
1706 bool hasValue = false;
1707 foreach (float x in source) {
1709 if (x > value || System.Double.IsNaN(value)) value = x;
1716 if (hasValue) return value;
1717 throw Error.NoElements();
1720 public static float? Max(this IEnumerable<float?> source) {
1721 if (source == null) throw Error.ArgumentNull("source");
1722 float? value = null;
1723 foreach (float? x in source) {
1724 if (x == null) continue;
1725 if (value == null || x > value || System.Single.IsNaN((float)value)) value = x;
1730 public static decimal Max(this IEnumerable<decimal> source) {
1731 if (source == null) throw Error.ArgumentNull("source");
1733 bool hasValue = false;
1734 foreach (decimal x in source) {
1736 if (x > value) value = x;
1743 if (hasValue) return value;
1744 throw Error.NoElements();
1747 public static decimal? Max(this IEnumerable<decimal?> source) {
1748 if (source == null) throw Error.ArgumentNull("source");
1749 decimal? value = null;
1750 foreach (decimal? x in source) {
1751 if (value == null || x > value) value = x;
1756 public static TSource Max<TSource>(this IEnumerable<TSource> source) {
1757 if (source == null) throw Error.ArgumentNull("source");
1758 Comparer<TSource> comparer = Comparer<TSource>.Default;
1759 TSource value = default(TSource);
1760 if (value == null) {
1761 foreach (TSource x in source) {
1762 if (x != null && (value == null || comparer.Compare(x, value) > 0))
1768 bool hasValue = false;
1769 foreach (TSource x in source) {
1771 if (comparer.Compare(x, value) > 0)
1779 if (hasValue) return value;
1780 throw Error.NoElements();
1784 public static int Max<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector) {
1785 return Enumerable.Max(Enumerable.Select(source, selector));
1788 public static int? Max<TSource>(this IEnumerable<TSource> source, Func<TSource, int?> selector) {
1789 return Enumerable.Max(Enumerable.Select(source, selector));
1792 public static long Max<TSource>(this IEnumerable<TSource> source, Func<TSource, long> selector) {
1793 return Enumerable.Max(Enumerable.Select(source, selector));
1796 public static long? Max<TSource>(this IEnumerable<TSource> source, Func<TSource, long?> selector) {
1797 return Enumerable.Max(Enumerable.Select(source, selector));
1800 public static float Max<TSource>(this IEnumerable<TSource> source, Func<TSource, float> selector) {
1801 return Enumerable.Max(Enumerable.Select(source, selector));
1804 public static float? Max<TSource>(this IEnumerable<TSource> source, Func<TSource, float?> selector) {
1805 return Enumerable.Max(Enumerable.Select(source, selector));
1808 public static double Max<TSource>(this IEnumerable<TSource> source, Func<TSource, double> selector) {
1809 return Enumerable.Max(Enumerable.Select(source, selector));
1812 public static double? Max<TSource>(this IEnumerable<TSource> source, Func<TSource, double?> selector) {
1813 return Enumerable.Max(Enumerable.Select(source, selector));
1816 public static decimal Max<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal> selector) {
1817 return Enumerable.Max(Enumerable.Select(source, selector));
1820 public static decimal? Max<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal?> selector) {
1821 return Enumerable.Max(Enumerable.Select(source, selector));
1824 public static TResult Max<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector) {
1825 return Enumerable.Max(Enumerable.Select(source, selector));
1828 public static double Average(this IEnumerable<int> source) {
1829 if (source == null) throw Error.ArgumentNull("source");
1833 foreach (int v in source) {
1838 if (count > 0) return (double)sum / count;
1839 throw Error.NoElements();
1842 public static double? Average(this IEnumerable<int?> source) {
1843 if (source == null) throw Error.ArgumentNull("source");
1847 foreach (int? v in source) {
1849 sum += v.GetValueOrDefault();
1854 if (count > 0) return (double)sum / count;
1858 public static double Average(this IEnumerable<long> source) {
1859 if (source == null) throw Error.ArgumentNull("source");
1863 foreach (long v in source) {
1868 if (count > 0) return (double)sum / count;
1869 throw Error.NoElements();
1872 public static double? Average(this IEnumerable<long?> source) {
1873 if (source == null) throw Error.ArgumentNull("source");
1877 foreach (long? v in source) {
1879 sum += v.GetValueOrDefault();
1884 if (count > 0) return (double)sum / count;
1888 public static float Average(this IEnumerable<float> source) {
1889 if (source == null) throw Error.ArgumentNull("source");
1893 foreach (float v in source) {
1898 if (count > 0) return (float)(sum / count);
1899 throw Error.NoElements();
1902 public static float? Average(this IEnumerable<float?> source) {
1903 if (source == null) throw Error.ArgumentNull("source");
1907 foreach (float? v in source) {
1909 sum += v.GetValueOrDefault();
1914 if (count > 0) return (float)(sum / count);
1918 public static double Average(this IEnumerable<double> source) {
1919 if (source == null) throw Error.ArgumentNull("source");
1923 foreach (double v in source) {
1928 if (count > 0) return sum / count;
1929 throw Error.NoElements();
1932 public static double? Average(this IEnumerable<double?> source) {
1933 if (source == null) throw Error.ArgumentNull("source");
1937 foreach (double? v in source) {
1939 sum += v.GetValueOrDefault();
1944 if (count > 0) return sum / count;
1948 public static decimal Average(this IEnumerable<decimal> source) {
1949 if (source == null) throw Error.ArgumentNull("source");
1953 foreach (decimal v in source) {
1958 if (count > 0) return sum / count;
1959 throw Error.NoElements();
1962 public static decimal? Average(this IEnumerable<decimal?> source) {
1963 if (source == null) throw Error.ArgumentNull("source");
1967 foreach (decimal? v in source) {
1969 sum += v.GetValueOrDefault();
1974 if (count > 0) return sum / count;
1978 public static double Average<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector) {
1979 return Enumerable.Average(Enumerable.Select(source, selector));
1982 public static double? Average<TSource>(this IEnumerable<TSource> source, Func<TSource, int?> selector) {
1983 return Enumerable.Average(Enumerable.Select(source, selector));
1986 public static double Average<TSource>(this IEnumerable<TSource> source, Func<TSource, long> selector) {
1987 return Enumerable.Average(Enumerable.Select(source, selector));
1990 public static double? Average<TSource>(this IEnumerable<TSource> source, Func<TSource, long?> selector) {
1991 return Enumerable.Average(Enumerable.Select(source, selector));
1994 public static float Average<TSource>(this IEnumerable<TSource> source, Func<TSource, float> selector) {
1995 return Enumerable.Average(Enumerable.Select(source, selector));
1998 public static float? Average<TSource>(this IEnumerable<TSource> source, Func<TSource, float?> selector) {
1999 return Enumerable.Average(Enumerable.Select(source, selector));
2002 public static double Average<TSource>(this IEnumerable<TSource> source, Func<TSource, double> selector) {
2003 return Enumerable.Average(Enumerable.Select(source, selector));
2006 public static double? Average<TSource>(this IEnumerable<TSource> source, Func<TSource, double?> selector) {
2007 return Enumerable.Average(Enumerable.Select(source, selector));
2010 public static decimal Average<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal> selector) {
2011 return Enumerable.Average(Enumerable.Select(source, selector));
2014 public static decimal? Average<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal?> selector) {
2015 return Enumerable.Average(Enumerable.Select(source, selector));
2021 // We have added some optimization in SZArrayHelper class to cache the enumerator of zero length arrays so
2022 // the enumerator will be created once per type.
2024 internal class EmptyEnumerable<TElement>
2026 public static readonly TElement[] Instance = new TElement[0];
2029 internal class IdentityFunction<TElement>
2031 public static Func<TElement, TElement> Instance {
2032 get { return x => x; }
2036 public interface IOrderedEnumerable<TElement> : IEnumerable<TElement>
2038 IOrderedEnumerable<TElement> CreateOrderedEnumerable<TKey>(Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending);
2041 #if SILVERLIGHT && !FEATURE_NETCORE
2042 public interface IGrouping<TKey, TElement> : IEnumerable<TElement>
2044 public interface IGrouping<out TKey, out TElement> : IEnumerable<TElement>
2050 public interface ILookup<TKey, TElement> : IEnumerable<IGrouping<TKey, TElement>>{
2052 IEnumerable<TElement> this[TKey key] { get; }
2053 bool Contains(TKey key);
2056 public class Lookup<TKey, TElement> : IEnumerable<IGrouping<TKey, TElement>>, ILookup<TKey, TElement>{
2057 IEqualityComparer<TKey> comparer;
2058 Grouping[] groupings;
2059 Grouping lastGrouping;
2062 internal static Lookup<TKey, TElement> Create<TSource>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer) {
2063 if (source == null) throw Error.ArgumentNull("source");
2064 if (keySelector == null) throw Error.ArgumentNull("keySelector");
2065 if (elementSelector == null) throw Error.ArgumentNull("elementSelector");
2066 Lookup<TKey, TElement> lookup = new Lookup<TKey, TElement>(comparer);
2067 foreach (TSource item in source) {
2068 lookup.GetGrouping(keySelector(item), true).Add(elementSelector(item));
2073 internal static Lookup<TKey, TElement> CreateForJoin(IEnumerable<TElement> source, Func<TElement, TKey> keySelector, IEqualityComparer<TKey> comparer) {
2074 Lookup<TKey, TElement> lookup = new Lookup<TKey, TElement>(comparer);
2075 foreach (TElement item in source) {
2076 TKey key = keySelector(item);
2077 if (key != null) lookup.GetGrouping(key, true).Add(item);
2082 Lookup(IEqualityComparer<TKey> comparer) {
2083 if (comparer == null) comparer = EqualityComparer<TKey>.Default;
2084 this.comparer = comparer;
2085 groupings = new Grouping[7];
2089 get { return count; }
2092 public IEnumerable<TElement> this[TKey key] {
2094 Grouping grouping = GetGrouping(key, false);
2095 if (grouping != null) return grouping;
2096 return EmptyEnumerable<TElement>.Instance;
2100 public bool Contains(TKey key) {
2101 return GetGrouping(key, false) != null;
2104 public IEnumerator<IGrouping<TKey, TElement>> GetEnumerator() {
2105 Grouping g = lastGrouping;
2110 } while (g != lastGrouping);
2114 public IEnumerable<TResult> ApplyResultSelector<TResult>(Func<TKey, IEnumerable<TElement>, TResult> resultSelector){
2115 Grouping g = lastGrouping;
2119 if (g.count != g.elements.Length) { Array.Resize<TElement>(ref g.elements, g.count); }
2120 yield return resultSelector(g.key, g.elements);
2121 }while (g != lastGrouping);
2125 IEnumerator IEnumerable.GetEnumerator() {
2126 return GetEnumerator();
2129 internal int InternalGetHashCode(TKey key)
2131 //Microsoft DevDivBugs 171937. work around comparer implementations that throw when passed null
2132 return (key == null) ? 0 : comparer.GetHashCode(key) & 0x7FFFFFFF;
2135 internal Grouping GetGrouping(TKey key, bool create) {
2136 int hashCode = InternalGetHashCode(key);
2137 for (Grouping g = groupings[hashCode % groupings.Length]; g != null; g = g.hashNext)
2138 if (g.hashCode == hashCode && comparer.Equals(g.key, key)) return g;
2140 if (count == groupings.Length) Resize();
2141 int index = hashCode % groupings.Length;
2142 Grouping g = new Grouping();
2144 g.hashCode = hashCode;
2145 g.elements = new TElement[1];
2146 g.hashNext = groupings[index];
2147 groupings[index] = g;
2148 if (lastGrouping == null) {
2152 g.next = lastGrouping.next;
2153 lastGrouping.next = g;
2163 int newSize = checked(count * 2 + 1);
2164 Grouping[] newGroupings = new Grouping[newSize];
2165 Grouping g = lastGrouping;
2168 int index = g.hashCode % newSize;
2169 g.hashNext = newGroupings[index];
2170 newGroupings[index] = g;
2171 } while (g != lastGrouping);
2172 groupings = newGroupings;
2175 internal class Grouping : IGrouping<TKey, TElement>, IList<TElement>
2178 internal int hashCode;
2179 internal TElement[] elements;
2181 internal Grouping hashNext;
2182 internal Grouping next;
2184 internal void Add(TElement element) {
2185 if (elements.Length == count) Array.Resize(ref elements, checked(count * 2));
2186 elements[count] = element;
2190 public IEnumerator<TElement> GetEnumerator() {
2191 for (int i = 0; i < count; i++) yield return elements[i];
2194 IEnumerator IEnumerable.GetEnumerator() {
2195 return GetEnumerator();
2198 // DDB195907: implement IGrouping<>.Key implicitly
2199 // so that WPF binding works on this property.
2204 int ICollection<TElement>.Count {
2205 get { return count; }
2208 bool ICollection<TElement>.IsReadOnly {
2209 get { return true; }
2212 void ICollection<TElement>.Add(TElement item) {
2213 throw Error.NotSupported();
2216 void ICollection<TElement>.Clear() {
2217 throw Error.NotSupported();
2220 bool ICollection<TElement>.Contains(TElement item) {
2221 return Array.IndexOf(elements, item, 0, count) >= 0;
2224 void ICollection<TElement>.CopyTo(TElement[] array, int arrayIndex) {
2225 Array.Copy(elements, 0, array, arrayIndex, count);
2228 bool ICollection<TElement>.Remove(TElement item) {
2229 throw Error.NotSupported();
2232 int IList<TElement>.IndexOf(TElement item) {
2233 return Array.IndexOf(elements, item, 0, count);
2236 void IList<TElement>.Insert(int index, TElement item) {
2237 throw Error.NotSupported();
2240 void IList<TElement>.RemoveAt(int index) {
2241 throw Error.NotSupported();
2244 TElement IList<TElement>.this[int index] {
2246 if (index < 0 || index >= count) throw Error.ArgumentOutOfRange("index");
2247 return elements[index];
2250 throw Error.NotSupported();
2257 internal class Set<TElement>
2263 IEqualityComparer<TElement> comparer;
2265 public Set() : this(null) { }
2267 public Set(IEqualityComparer<TElement> comparer) {
2268 if (comparer == null) comparer = EqualityComparer<TElement>.Default;
2269 this.comparer = comparer;
2270 buckets = new int[7];
2271 slots = new Slot[7];
2275 // If value is not in set, add it and return true; otherwise return false
2276 public bool Add(TElement value) {
2277 return !Find(value, true);
2280 // Check whether value is in set
2281 public bool Contains(TElement value) {
2282 return Find(value, false);
2285 // If value is in set, remove it and return true; otherwise return false
2286 public bool Remove(TElement value) {
2287 int hashCode = InternalGetHashCode(value);
2288 int bucket = hashCode % buckets.Length;
2290 for (int i = buckets[bucket] - 1; i >= 0; last = i, i = slots[i].next) {
2291 if (slots[i].hashCode == hashCode && comparer.Equals(slots[i].value, value)) {
2293 buckets[bucket] = slots[i].next + 1;
2296 slots[last].next = slots[i].next;
2298 slots[i].hashCode = -1;
2299 slots[i].value = default(TElement);
2300 slots[i].next = freeList;
2308 bool Find(TElement value, bool add) {
2309 int hashCode = InternalGetHashCode(value);
2310 for (int i = buckets[hashCode % buckets.Length] - 1; i >= 0; i = slots[i].next) {
2311 if (slots[i].hashCode == hashCode && comparer.Equals(slots[i].value, value)) return true;
2315 if (freeList >= 0) {
2317 freeList = slots[index].next;
2320 if (count == slots.Length) Resize();
2324 int bucket = hashCode % buckets.Length;
2325 slots[index].hashCode = hashCode;
2326 slots[index].value = value;
2327 slots[index].next = buckets[bucket] - 1;
2328 buckets[bucket] = index + 1;
2334 int newSize = checked(count * 2 + 1);
2335 int[] newBuckets = new int[newSize];
2336 Slot[] newSlots = new Slot[newSize];
2337 Array.Copy(slots, 0, newSlots, 0, count);
2338 for (int i = 0; i < count; i++) {
2339 int bucket = newSlots[i].hashCode % newSize;
2340 newSlots[i].next = newBuckets[bucket] - 1;
2341 newBuckets[bucket] = i + 1;
2343 buckets = newBuckets;
2347 internal int InternalGetHashCode(TElement value)
2349 //Microsoft DevDivBugs 171937. work around comparer implementations that throw when passed null
2350 return (value == null) ? 0 : comparer.GetHashCode(value) & 0x7FFFFFFF;
2353 internal struct Slot
2355 internal int hashCode;
2356 internal TElement value;
2361 internal class GroupedEnumerable<TSource, TKey, TElement, TResult> : IEnumerable<TResult>{
2362 IEnumerable<TSource> source;
2363 Func<TSource, TKey> keySelector;
2364 Func<TSource, TElement> elementSelector;
2365 IEqualityComparer<TKey> comparer;
2366 Func<TKey, IEnumerable<TElement>, TResult> resultSelector;
2368 public GroupedEnumerable(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<TKey, IEnumerable<TElement>, TResult> resultSelector, IEqualityComparer<TKey> comparer){
2369 if (source == null) throw Error.ArgumentNull("source");
2370 if (keySelector == null) throw Error.ArgumentNull("keySelector");
2371 if (elementSelector == null) throw Error.ArgumentNull("elementSelector");
2372 if (resultSelector == null) throw Error.ArgumentNull("resultSelector");
2373 this.source = source;
2374 this.keySelector = keySelector;
2375 this.elementSelector = elementSelector;
2376 this.comparer = comparer;
2377 this.resultSelector = resultSelector;
2380 public IEnumerator<TResult> GetEnumerator(){
2381 Lookup<TKey, TElement> lookup = Lookup<TKey, TElement>.Create<TSource>(source, keySelector, elementSelector, comparer);
2382 return lookup.ApplyResultSelector(resultSelector).GetEnumerator();
2385 IEnumerator IEnumerable.GetEnumerator(){
2386 return GetEnumerator();
2390 internal class GroupedEnumerable<TSource, TKey, TElement> : IEnumerable<IGrouping<TKey, TElement>>
2392 IEnumerable<TSource> source;
2393 Func<TSource, TKey> keySelector;
2394 Func<TSource, TElement> elementSelector;
2395 IEqualityComparer<TKey> comparer;
2397 public GroupedEnumerable(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer) {
2398 if (source == null) throw Error.ArgumentNull("source");
2399 if (keySelector == null) throw Error.ArgumentNull("keySelector");
2400 if (elementSelector == null) throw Error.ArgumentNull("elementSelector");
2401 this.source = source;
2402 this.keySelector = keySelector;
2403 this.elementSelector = elementSelector;
2404 this.comparer = comparer;
2407 public IEnumerator<IGrouping<TKey, TElement>> GetEnumerator() {
2408 return Lookup<TKey, TElement>.Create<TSource>(source, keySelector, elementSelector, comparer).GetEnumerator();
2411 IEnumerator IEnumerable.GetEnumerator() {
2412 return GetEnumerator();
2416 internal abstract class OrderedEnumerable<TElement> : IOrderedEnumerable<TElement>
2418 internal IEnumerable<TElement> source;
2420 public IEnumerator<TElement> GetEnumerator() {
2421 Buffer<TElement> buffer = new Buffer<TElement>(source);
2422 if (buffer.count > 0) {
2423 EnumerableSorter<TElement> sorter = GetEnumerableSorter(null);
2424 int[] map = sorter.Sort(buffer.items, buffer.count);
2426 for (int i = 0; i < buffer.count; i++) yield return buffer.items[map[i]];
2430 internal abstract EnumerableSorter<TElement> GetEnumerableSorter(EnumerableSorter<TElement> next);
2432 IEnumerator IEnumerable.GetEnumerator() {
2433 return GetEnumerator();
2436 IOrderedEnumerable<TElement> IOrderedEnumerable<TElement>.CreateOrderedEnumerable<TKey>(Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending) {
2437 OrderedEnumerable<TElement, TKey> result = new OrderedEnumerable<TElement, TKey>(source, keySelector, comparer, descending);
2438 result.parent = this;
2443 internal class OrderedEnumerable<TElement, TKey> : OrderedEnumerable<TElement>
2445 internal OrderedEnumerable<TElement> parent;
2446 internal Func<TElement, TKey> keySelector;
2447 internal IComparer<TKey> comparer;
2448 internal bool descending;
2450 internal OrderedEnumerable(IEnumerable<TElement> source, Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending) {
2451 if (source == null) throw Error.ArgumentNull("source");
2452 if (keySelector == null) throw Error.ArgumentNull("keySelector");
2453 this.source = source;
2455 this.keySelector = keySelector;
2456 this.comparer = comparer != null ? comparer : Comparer<TKey>.Default;
2457 this.descending = descending;
2460 internal override EnumerableSorter<TElement> GetEnumerableSorter(EnumerableSorter<TElement> next) {
2461 EnumerableSorter<TElement> sorter = new EnumerableSorter<TElement, TKey>(keySelector, comparer, descending, next);
2462 if (parent != null) sorter = parent.GetEnumerableSorter(sorter);
2467 internal abstract class EnumerableSorter<TElement>
2469 internal abstract void ComputeKeys(TElement[] elements, int count);
2471 internal abstract int CompareKeys(int index1, int index2);
2473 internal int[] Sort(TElement[] elements, int count) {
2474 ComputeKeys(elements, count);
2475 int[] map = new int[count];
2476 for (int i = 0; i < count; i++) map[i] = i;
2477 QuickSort(map, 0, count - 1);
2481 void QuickSort(int[] map, int left, int right) {
2485 int x = map[i + ((j - i) >> 1)];
2487 while (i < map.Length && CompareKeys(x, map[i]) > 0) i++;
2488 while (j >= 0 && CompareKeys(x, map[j]) < 0) j--;
2498 if (j - left <= right - i) {
2499 if (left < j) QuickSort(map, left, j);
2503 if (i < right) QuickSort(map, i, right);
2506 } while (left < right);
2510 internal class EnumerableSorter<TElement, TKey> : EnumerableSorter<TElement>
2512 internal Func<TElement, TKey> keySelector;
2513 internal IComparer<TKey> comparer;
2514 internal bool descending;
2515 internal EnumerableSorter<TElement> next;
2516 internal TKey[] keys;
2518 internal EnumerableSorter(Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending, EnumerableSorter<TElement> next) {
2519 this.keySelector = keySelector;
2520 this.comparer = comparer;
2521 this.descending = descending;
2525 internal override void ComputeKeys(TElement[] elements, int count) {
2526 keys = new TKey[count];
2527 for (int i = 0; i < count; i++) keys[i] = keySelector(elements[i]);
2528 if (next != null) next.ComputeKeys(elements, count);
2531 internal override int CompareKeys(int index1, int index2) {
2532 int c = comparer.Compare(keys[index1], keys[index2]);
2534 if (next == null) return index1 - index2;
2535 return next.CompareKeys(index1, index2);
2537 return descending ? -c : c;
2541 struct Buffer<TElement>
2543 internal TElement[] items;
2546 internal Buffer(IEnumerable<TElement> source) {
2547 TElement[] items = null;
2549 ICollection<TElement> collection = source as ICollection<TElement>;
2550 if (collection != null) {
2551 count = collection.Count;
2553 items = new TElement[count];
2554 collection.CopyTo(items, 0);
2558 foreach (TElement item in source) {
2559 if (items == null) {
2560 items = new TElement[4];
2562 else if (items.Length == count) {
2563 TElement[] newItems = new TElement[checked(count * 2)];
2564 Array.Copy(items, 0, newItems, 0, count);
2567 items[count] = item;
2575 internal TElement[] ToArray() {
2576 if (count == 0) return new TElement[0];
2577 if (items.Length == count) return items;
2578 TElement[] result = new TElement[count];
2579 Array.Copy(items, 0, result, 0, count);
2585 /// This class provides the items view for the Enumerable
2587 /// <typeparam name="T"></typeparam>
2588 internal sealed class SystemCore_EnumerableDebugView<T>
2590 public SystemCore_EnumerableDebugView(IEnumerable<T> enumerable)
2592 if (enumerable == null)
2594 throw new ArgumentNullException("enumerable");
2597 this.enumerable = enumerable;
2600 [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)]
2605 List<T> tempList = new List<T>();
2606 IEnumerator<T> currentEnumerator = this.enumerable.GetEnumerator();
2608 if (currentEnumerator != null)
2610 for(count = 0; currentEnumerator.MoveNext(); count++)
2612 tempList.Add(currentEnumerator.Current);
2617 throw new SystemCore_EnumerableDebugViewEmptyException();
2619 cachedCollection = new T[this.count];
2620 tempList.CopyTo(cachedCollection, 0);
2621 return cachedCollection;
2625 [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
2626 private IEnumerable<T> enumerable;
2628 [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
2629 private T[] cachedCollection;
2631 [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
2635 internal sealed class SystemCore_EnumerableDebugViewEmptyException : Exception
2641 return Strings.EmptyEnumerable;
2646 internal sealed class SystemCore_EnumerableDebugView
2648 public SystemCore_EnumerableDebugView(IEnumerable enumerable)
2650 if (enumerable == null)
2652 throw new ArgumentNullException("enumerable");
2655 this.enumerable = enumerable;
2657 cachedCollection = null;
2660 [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)]
2661 public object[] Items
2665 List<object> tempList = new List<object>();
2666 IEnumerator currentEnumerator = this.enumerable.GetEnumerator();
2668 if (currentEnumerator != null)
2670 for (count = 0; currentEnumerator.MoveNext(); count++)
2672 tempList.Add(currentEnumerator.Current);
2677 throw new SystemCore_EnumerableDebugViewEmptyException();
2679 cachedCollection = new object[this.count];
2680 tempList.CopyTo(cachedCollection, 0);
2681 return cachedCollection;
2685 [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
2686 private IEnumerable enumerable;
2688 [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
2689 private object[] cachedCollection;
2691 [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]