Throw
}
+#if !FULL_AOT_RUNTIME
static class PredicateOf<T> {
public static readonly Func<T, bool> Always = (t) => true;
}
+#endif
static class Function<T> {
public static readonly Func<T, T> Identity = (t) => t;
// if zero elements and treat the first element differently
using (var enumerator = source.GetEnumerator ()) {
if (!enumerator.MoveNext ())
- throw new InvalidOperationException ("No elements in source list");
+ throw EmptySequence ();
TSource folded = enumerator.Current;
while (enumerator.MoveNext ())
count++;
}
if (count == 0)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
return total / (double) count;
}
count++;
}
if (count == 0)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
return total / (double) count;
}
count++;
}
if (count == 0)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
return total / count;
}
count++;
}
if (count == 0)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
return total / count;
}
count++;
}
if (count == 0)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
return total / count;
}
count++;
}
if (count == 0)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
return total / (double) count;
}
count++;
}
if (count == 0)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
return total / (double) count;
}
count++;
}
if (count == 0)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
return total / count;
}
count++;
}
if (count == 0)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
return total / count;
}
count++;
}
if (count == 0)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
return total / count;
}
int counter = 0;
using (var enumerator = source.GetEnumerator ())
while (enumerator.MoveNext ())
- counter++;
+ checked { counter++; }
return counter;
}
- public static int Count<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
+ public static int Count<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
- Check.SourceAndSelector (source, selector);
+ Check.SourceAndSelector (source, predicate);
int counter = 0;
foreach (var element in source)
- if (selector (element))
- counter++;
+ if (predicate (element))
+ checked { counter++; }
return counter;
}
{
var items = new HashSet<TSource> (second, comparer);
foreach (var element in first) {
- if (!items.Contains (element, comparer))
+ if (items.Add (element))
yield return element;
}
}
return element;
if (fallback == Fallback.Throw)
- throw new InvalidOperationException ();
+ throw NoMatchingElement ();
return default (TSource);
}
}
}
- throw new InvalidOperationException ("The source sequence is empty");
+ throw EmptySequence ();
}
public static TSource First<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
Check.Source (source);
+#if !FULL_AOT_RUNTIME
return source.First (PredicateOf<TSource>.Always, Fallback.Default);
+#else
+ // inline the code to reduce dependency o generic causing AOT errors on device (e.g. bug #3285)
+ foreach (var element in source)
+ return element;
+
+ return default (TSource);
+#endif
}
public static TSource FirstOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
return item;
if (fallback == Fallback.Throw)
- throw new InvalidOperationException ();
+ throw NoMatchingElement ();
return item;
}
var collection = source as ICollection<TSource>;
if (collection != null && collection.Count == 0)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
var list = source as IList<TSource>;
if (list != null)
return list [list.Count - 1];
+#if !FULL_AOT_RUNTIME
return source.Last (PredicateOf<TSource>.Always, Fallback.Throw);
- }
+#else
+ var empty = true;
+ var item = default (TSource);
+
+ foreach (var element in source) {
+ item = element;
+ empty = false;
+ }
+
+ if (!empty)
+ return item;
+
+ throw EmptySequence ();
+#endif
+ }
public static TSource Last<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (list != null)
return list.Count > 0 ? list [list.Count - 1] : default (TSource);
+#if !FULL_AOT_RUNTIME
return source.Last (PredicateOf<TSource>.Always, Fallback.Default);
+#else
+ var empty = true;
+ var item = default (TSource);
+
+ foreach (var element in source) {
+ item = element;
+ empty = false;
+ }
+
+ if (!empty)
+ return item;
+
+ return item;
+#endif
}
public static TSource LastOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
return counter;
}
- public static long LongCount<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> selector)
+ public static long LongCount<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
- Check.SourceAndSelector (source, selector);
+ Check.SourceAndSelector (source, predicate);
long counter = 0;
foreach (TSource element in source)
- if (selector (element))
+ if (predicate (element))
counter++;
return counter;
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw EmptySequence();
return max;
}
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
return max;
}
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
return max;
}
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
return max;
}
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
return max;
}
max = element;
}
if (empty)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
}
return max;
}
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw NoMatchingElement ();
return max;
}
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw NoMatchingElement ();
return max;
}
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw NoMatchingElement ();
return max;
}
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw NoMatchingElement ();
return max;
}
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw NoMatchingElement ();
return max;
}
}
if (empty)
- throw new InvalidOperationException ();
+ throw NoMatchingElement ();
return initValue;
}
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
return min;
}
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
return min;
}
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
return min;
}
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
return min;
}
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
return min;
}
min = element;
}
if (empty)
- throw new InvalidOperationException ();
+ throw EmptySequence ();
}
return min;
}
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw NoMatchingElement ();
return min;
}
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw NoMatchingElement ();
return min;
}
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw NoMatchingElement ();
return min;
}
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw NoMatchingElement ();
return min;
}
empty = false;
}
if (empty)
- throw new InvalidOperationException ();
+ throw NoMatchingElement ();
return min;
}
if (count < 0)
throw new ArgumentOutOfRangeException ("count");
- long upto = ((long) start + count) - 1;
-
- if (upto > int.MaxValue)
+ if (((long) start + count) - 1L > int.MaxValue)
throw new ArgumentOutOfRangeException ();
- return CreateRangeIterator (start, (int) upto);
+ return CreateRangeIterator (start, count);
}
- static IEnumerable<int> CreateRangeIterator (int start, int upto)
+ static IEnumerable<int> CreateRangeIterator (int start, int count)
{
- for (int i = start; i <= upto; i++)
- yield return i;
+ for (int i = 0; i < count; i++)
+ yield return start + i;
}
#endregion
static IEnumerable<TSource> CreateReverseIterator<TSource> (IEnumerable<TSource> source)
{
- var list = source as IList<TSource>;
- if (list == null)
- list = new List<TSource> (source);
+ var array = source.ToArray ();
- for (int i = list.Count - 1; i >= 0; i--)
- yield return list [i];
+ for (int i = array.Length - 1; i >= 0; i--)
+ yield return array [i];
}
#endregion
}
public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
- Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
+ Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
{
- Check.SourceAndCollectionSelectors (source, collectionSelector, selector);
+ Check.SourceAndCollectionSelectors (source, collectionSelector, resultSelector);
- return CreateSelectManyIterator (source, collectionSelector, selector);
+ return CreateSelectManyIterator (source, collectionSelector, resultSelector);
}
static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
}
public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult> (this IEnumerable<TSource> source,
- Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> selector)
+ Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
{
- Check.SourceAndCollectionSelectors (source, collectionSelector, selector);
+ Check.SourceAndCollectionSelectors (source, collectionSelector, resultSelector);
- return CreateSelectManyIterator (source, collectionSelector, selector);
+ return CreateSelectManyIterator (source, collectionSelector, resultSelector);
}
static IEnumerable<TResult> CreateSelectManyIterator<TSource, TCollection, TResult> (IEnumerable<TSource> source,
continue;
if (found)
- throw new InvalidOperationException ();
+ throw MoreThanOneMatchingElement ();
found = true;
item = element;
}
if (!found && fallback == Fallback.Throw)
- throw new InvalidOperationException ();
+ throw NoMatchingElement ();
return item;
}
{
Check.Source (source);
+#if !FULL_AOT_RUNTIME
return source.Single (PredicateOf<TSource>.Always, Fallback.Throw);
- }
+#else
+ var found = false;
+ var item = default (TSource);
+
+ foreach (var element in source) {
+ if (found)
+ throw MoreThanOneElement ();
+
+ found = true;
+ item = element;
+ }
+
+ if (!found)
+ throw NoMatchingElement ();
+
+ return item;
+#endif
+ }
public static TSource Single<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
{
Check.Source (source);
+#if !FULL_AOT_RUNTIME
return source.Single (PredicateOf<TSource>.Always, Fallback.Default);
- }
+#else
+ var found = false;
+ var item = default (TSource);
+
+ foreach (var element in source) {
+ if (found)
+ throw MoreThanOneMatchingElement ();
+
+ found = true;
+ item = element;
+ }
+
+ return item;
+#endif
+ }
public static TSource SingleOrDefault<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
{
Check.SourceAndKeySelector (source, keySelector);
+#if FULL_AOT_RUNTIME
+ var oe = source as OrderedEnumerable <TSource>;
+ if (oe != null)
+ return oe.CreateOrderedEnumerable (keySelector, comparer, false);
+#endif
+
return source.CreateOrderedEnumerable (keySelector, comparer, false);
}
{
Check.SourceAndKeySelector (source, keySelector);
+#if FULL_AOT_RUNTIME
+ var oe = source as OrderedEnumerable <TSource>;
+ if (oe != null)
+ return oe.CreateOrderedEnumerable (keySelector, comparer, true);
+#endif
return source.CreateOrderedEnumerable (keySelector, comparer, true);
}
{
Check.Source (source);
+ TSource[] array;
var collection = source as ICollection<TSource>;
if (collection != null) {
- var array = new TSource [collection.Count];
+ if (collection.Count == 0)
+ return EmptyOf<TSource>.Instance;
+
+ array = new TSource [collection.Count];
collection.CopyTo (array, 0);
return array;
}
- return new List<TSource> (source).ToArray ();
+ int pos = 0;
+ array = EmptyOf<TSource>.Instance;
+ foreach (var element in source) {
+ if (pos == array.Length) {
+ if (pos == 0)
+ array = new TSource [4];
+ else
+ Array.Resize (ref array, pos * 2);
+ }
+
+ array[pos++] = element;
+ }
+
+ if (pos != array.Length)
+ Array.Resize (ref array, pos);
+
+ return array;
}
#endregion
public static ILookup<TKey, TSource> ToLookup<TSource, TKey> (this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
{
- return ToLookup<TSource, TKey, TSource> (source, keySelector, element => element, comparer);
+ return ToLookup<TSource, TKey, TSource> (source, keySelector, Function<TSource>.Identity, comparer);
}
public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement> (this IEnumerable<TSource> source,
}
foreach (var element in second) {
- if (! items.Contains (element, comparer)) {
+ if (! items.Contains (element)) {
items.Add (element);
yield return element;
}
#endregion
-#if NET_4_0
+#if NET_4_0
#region Zip
public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult> (this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
{
Check.SourceAndPredicate (source, predicate);
+ // It cannot be IList<TSource> because it may break on user implementation
+ var array = source as TSource[];
+ if (array != null)
+ return CreateWhereIterator (array, predicate);
+
return CreateWhereIterator (source, predicate);
}
yield return element;
}
+ static IEnumerable<TSource> CreateWhereIterator<TSource> (TSource[] source, Func<TSource, bool> predicate)
+ {
+ for (int i = 0; i < source.Length; ++i) {
+ var element = source [i];
+ if (predicate (element))
+ yield return element;
+ }
+ }
+
public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
{
Check.SourceAndPredicate (source, predicate);
+ var array = source as TSource[];
+ if (array != null)
+ return CreateWhereIterator (array, predicate);
+
return CreateWhereIterator (source, predicate);
}
- static IEnumerable<TSource> CreateWhereIterator<TSource> (this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
+ static IEnumerable<TSource> CreateWhereIterator<TSource> (IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
{
int counter = 0;
foreach (TSource element in source) {
}
}
+ static IEnumerable<TSource> CreateWhereIterator<TSource> (TSource[] source, Func<TSource, int, bool> predicate)
+ {
+ for (int i = 0; i < source.Length; ++i) {
+ var element = source [i];
+ if (predicate (element, i))
+ yield return element;
+ }
+ }
+
#endregion
internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource> (this IEnumerable<TSource> source)
return new ReadOnlyCollection<TSource> (source.ToArray<TSource> ());
}
+
+ #region Exception helpers
+
+ static Exception EmptySequence ()
+ {
+ return new InvalidOperationException (Locale.GetText ("Sequence contains no elements"));
+ }
+ static Exception NoMatchingElement ()
+ {
+ return new InvalidOperationException (Locale.GetText ("Sequence contains no matching element"));
+ }
+ static Exception MoreThanOneElement ()
+ {
+ return new InvalidOperationException (Locale.GetText ("Sequence contains more than one element"));
+ }
+ static Exception MoreThanOneMatchingElement ()
+ {
+ return new InvalidOperationException (Locale.GetText ("Sequence contains more than one matching element"));
+ }
+
+ #endregion
}
}